diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellRenderer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellRenderer.java
index 44d8f71e443fe42cad922df2dc0e09899961be3e..fdee3d801b30af1bd933579a1acd44b4e8e086cd 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellRenderer.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellRenderer.java
@@ -47,7 +47,7 @@ public class UploadStatusTableCellRenderer implements TableCellRenderer
 
     private final JPanel fixErrorsPanel = new JPanel();
 
-    private final JProgressBar progressBar = new JProgressBar();
+    private final JProgressBar progressBar = new JProgressBar(0, 100);
 
     private final JLabel progressLabel = new JLabel();
 
@@ -139,6 +139,9 @@ public class UploadStatusTableCellRenderer implements TableCellRenderer
                 break;
             case QUEUED_FOR_UPLOAD:
             case UPLOADING:
+            	panel = progressPanel;
+            	progressBar.setValue(dataSetInfo.getPercentageDownloaded());
+            	break;
             case STALLED:
                 panel = progressPanel;
                 progressBar.setValue(0);
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java
index eb06c48f2d2fd6c8007ad1392532f76606f2eed1..2837655cbfcaf72cd3a7b6c26fb254bcf9147558 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java
@@ -25,6 +25,7 @@ import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.openbis.dss.client.api.gui.model.DataSetUploadClientModel.NewDataSetInfo;
 import ch.systemsx.cisd.openbis.dss.client.api.gui.model.DataSetUploadClientModel.NewDataSetInfo.Status;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.UploadObserver;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType;
@@ -64,7 +65,7 @@ final class DataSetUploadOperation implements Runnable
     {
         try
         {
-            if (newDataSetInfo.getStatus() == NewDataSetInfo.Status.QUEUED_FOR_UPLOAD)
+        	if (newDataSetInfo.getStatus() == NewDataSetInfo.Status.QUEUED_FOR_UPLOAD)
             {
                 newDataSetInfo.setStatus(Status.UPLOADING);
                 tableModel.fireChanged(newDataSetInfo, Status.UPLOADING);
@@ -72,6 +73,15 @@ final class DataSetUploadOperation implements Runnable
                 NewDataSetDTO cleanDto =
                         clientModel.cleanNewDataSetDTO(newDataSetInfo.getNewDataSetBuilder()
                                 .asNewDataSetDTO());
+                cleanDto.addUploadObserver(new UploadObserver() {
+					@Override
+					public void updateTotalBytesRead(long totalBytesRead) {
+						double totalFileSize = newDataSetInfo.getTotalFileSize();
+						int percent = (int)((totalBytesRead / totalFileSize) * 100);
+						newDataSetInfo.updateProgress(percent, totalBytesRead); 
+						tableModel.fireChanged(newDataSetInfo, Status.UPLOADING);
+					}
+                });
                 clientModel.getOpenBISService().putDataSet(cleanDto,
                         newDataSetInfo.getNewDataSetBuilder().getFile());
             }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
index efd396afde8828a487c67b244deb8078e9161e7a..536eb9bf83564ae06355f0dd8a96d52fde08a3b5 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.dss.client.api.v1.impl;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -475,14 +476,36 @@ class AuthenticatedState extends AbstractDssComponentState
     }
 
     @Override
-    public IDataSetDss putDataSet(NewDataSetDTO newDataset, File dataSetFile)
+    public IDataSetDss putDataSet(final NewDataSetDTO newDataset, File dataSetFile)
             throws IllegalStateException, EnvironmentFailureException
     {
         final IDssServiceRpcGeneric dssService = getServiceForPutDataStore();
         ConcatenatedContentInputStream fileInputStream =
                 new ConcatenatedContentInputStream(true, getContentForFileInfos(
                         dataSetFile.getPath(), newDataset.getFileInfos()));
-        String code = dssService.putDataSet(sessionToken, newDataset, fileInputStream);
+        
+        FilterInputStream progressInputStream = new FilterInputStream(fileInputStream) {
+        	long totalRead = 0;
+            public int read() throws IOException {
+            	totalRead += 1;
+            	newDataset.notifyUploadProgress(totalRead);
+                return in.read();
+            }
+            
+            public int read(byte b[]) throws IOException {
+            	totalRead += b.length;
+            	newDataset.notifyUploadProgress(totalRead);
+                return read(b, 0, b.length);
+            }
+            
+            public int read(byte b[], int off, int len) throws IOException {
+            	totalRead += len;
+            	newDataset.notifyUploadProgress(totalRead);
+                return in.read(b, off, len);
+            }
+        };
+        
+        String code = dssService.putDataSet(sessionToken, newDataset, progressInputStream);
         return new DataSetDss(code, dssService, this);
     }
 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java
index aaa14210d9087a06cce2afff9ae8a5c1c7cdf1f6..8fec1b6b70256ce05213ebec535f46d2e8b75d62 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java
@@ -39,6 +39,21 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
 @JsonObject("NewDataSetDTO")
 public class NewDataSetDTO implements Serializable
 {
+ 
+	//TO-DO - Fix Hack: The only reason to have this property as transient is because Jackson is not ignoring it using @JsonIgnore
+    transient UploadObserver uploadObserver = null; 
+    
+    public void addUploadObserver(UploadObserver uploadObserver)
+    {
+        this.uploadObserver = uploadObserver;
+    }
+    
+    public void notifyUploadProgress(long totalBytesRead) {
+    	if(uploadObserver != null) {
+    		uploadObserver.updateTotalBytesRead(totalBytesRead);
+    	}
+    }
+    
     public static String DEFAULT_DATA_SET_FOLDER_NAME = "original";
 
     /**
@@ -278,4 +293,4 @@ public class NewDataSetDTO implements Serializable
     {
         dataSetMetadata.setParentDataSetCodes(codesOrNull);
     }
-}
+}
\ No newline at end of file
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/UploadObserver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/UploadObserver.java
new file mode 100644
index 0000000000000000000000000000000000000000..04b5b5cc6a6f39047d707638d3c3a148b1330fd4
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/UploadObserver.java
@@ -0,0 +1,5 @@
+package ch.systemsx.cisd.openbis.dss.generic.shared.api.v1;
+
+public interface UploadObserver {
+   	 abstract void updateTotalBytesRead(long totalBytesRead);
+}