diff --git a/app/components/service/service.html b/app/components/service/service.html
index 16245f8e2..ba298a3d9 100644
--- a/app/components/service/service.html
+++ b/app/components/service/service.html
@@ -38,6 +38,7 @@
               <td>ID</td>
               <td>
                 {{ service.Id }}
+                <button class="btn btn-xs btn-primary" ng-click="forceUpdateService(service)"><i class="fa fa-refresh space-right" aria-hidden="true" ng-disabled="isUpdating" ng-if="applicationState.endpoint.apiVersion >= 1.25"></i>Force update this service</button>
                 <button class="btn btn-xs btn-danger" ng-click="removeService()"><i class="fa fa-trash space-right" aria-hidden="true" ng-disabled="isUpdating"></i>Delete this service</button>
               </td>
             </tr>
diff --git a/app/components/service/serviceController.js b/app/components/service/serviceController.js
index 74c72a02a..2c4a5602e 100644
--- a/app/components/service/serviceController.js
+++ b/app/components/service/serviceController.js
@@ -168,7 +168,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll,
     }
   };
 
-  $scope.addLogDriverOpt = function addLogDriverOpt(service) {    
+  $scope.addLogDriverOpt = function addLogDriverOpt(service) {
     service.LogDriverOpts.push({ key: '', value: '', originalValue: '' });
     updateServiceArray(service, 'LogDriverOpts', service.LogDriverOpts);
   };
@@ -182,16 +182,16 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll,
     if (variable.value !== variable.originalValue || variable.key !== variable.originalKey) {
       updateServiceArray(service, 'LogDriverOpts', service.LogDriverOpts);
     }
-  };   
-  $scope.updateLogDriverName = function updateLogDriverName(service) {    
-    updateServiceArray(service, 'LogDriverName', service.LogDriverName);    
-  };    
+  };
+  $scope.updateLogDriverName = function updateLogDriverName(service) {
+    updateServiceArray(service, 'LogDriverName', service.LogDriverName);
+  };
 
   $scope.addHostsEntry = function (service) {
     if (!service.Hosts) {
       service.Hosts = [];
     }
-    service.Hosts.push({ hostname: '', ip: '' });    
+    service.Hosts.push({ hostname: '', ip: '' });
   };
   $scope.removeHostsEntry = function(service, index) {
     var removedElement = service.Hosts.splice(index, 1);
@@ -199,9 +199,9 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll,
       updateServiceArray(service, 'Hosts', service.Hosts);
     }
   };
-  $scope.updateHostsEntry = function(service, entry) {  
+  $scope.updateHostsEntry = function(service, entry) {
     updateServiceArray(service, 'Hosts', service.Hosts);
-  };  
+  };
 
   $scope.cancelChanges = function cancelChanges(service, keys) {
     if (keys) { // clean out the keys only from the list of modified keys
@@ -239,7 +239,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll,
     config.TaskTemplate.ContainerSpec.Secrets = service.ServiceSecrets ? service.ServiceSecrets.map(SecretHelper.secretConfig) : [];
     config.TaskTemplate.ContainerSpec.Configs = service.ServiceConfigs ? service.ServiceConfigs.map(ConfigHelper.configConfig) : [];
     config.TaskTemplate.ContainerSpec.Hosts = service.Hosts ? ServiceHelper.translateHostnameIPToHostsEntries(service.Hosts) : [];
-    
+
     if (service.Mode === 'replicated') {
       config.Mode.Replicated.Replicas = service.Replicas;
     }
@@ -279,17 +279,17 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll,
       MaxAttempts: service.RestartMaxAttempts,
       Window: ServiceHelper.translateHumanDurationToNanos(service.RestartWindow) || 0
     };
-    
+
     config.TaskTemplate.LogDriver = null;
-    if (service.LogDriverName) {      
+    if (service.LogDriverName) {
       config.TaskTemplate.LogDriver = { Name: service.LogDriverName };
       if (service.LogDriverName !== 'none') {
         var logOpts = ServiceHelper.translateKeyValueToLogDriverOpts(service.LogDriverOpts);
         if (Object.keys(logOpts).length !== 0 && logOpts.constructor === Object) {
           config.TaskTemplate.LogDriver.Options = logOpts;
         }
-      }      
-    }    
+      }
+    }
 
     if (service.Ports) {
       service.Ports.forEach(function (binding) {
@@ -338,6 +338,32 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll,
     });
   }
 
+  $scope.forceUpdateService = function(service) {
+    ModalService.confirmServiceForceUpdate(
+      'Do you want to force update this service? All the tasks associated to the selected service(s) will be recreated.',
+      function onConfirm(confirmed) {
+        if(!confirmed) { return; }
+        forceUpdateService(service);
+      }
+    );
+  };
+
+  function forceUpdateService(service) {
+    var config = ServiceHelper.serviceToConfig(service.Model);
+    // As explained in https://github.com/docker/swarmkit/issues/2364 ForceUpdate can accept a random
+    // value or an increment of the counter value to force an update.
+    config.TaskTemplate.ForceUpdate++;
+    ServiceService.update(service, config)
+    .then(function success(data) {
+      Notifications.success('Service successfully updated', service.Name);
+      $scope.cancelChanges({});
+      initView();
+    })
+    .catch(function error(err) {
+      Notifications.error('Failure', err, 'Unable to force update service', service.Name);
+    });
+  }
+
   function translateServiceArrays(service) {
     service.ServiceSecrets = service.Secrets ? service.Secrets.map(SecretHelper.flattenSecret) : [];
     service.ServiceConfigs = service.Configs ? service.Configs.map(ConfigHelper.flattenConfig) : [];
@@ -365,7 +391,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll,
   }
 
   function initView() {
-    var apiVersion = $scope.applicationState.endpoint.apiVersion;  
+    var apiVersion = $scope.applicationState.endpoint.apiVersion;
 
     ServiceService.service($transition$.params().id)
     .then(function success(data) {
diff --git a/app/components/services/services.html b/app/components/services/services.html
index 3c23ac6cd..48eebed2e 100644
--- a/app/components/services/services.html
+++ b/app/components/services/services.html
@@ -16,7 +16,9 @@
     show-ownership-column="applicationState.application.authentication"
     remove-action="removeAction"
     scale-action="scaleAction"
+    force-update-action="forceUpdateAction"
     swarm-manager-ip="swarmManagerIP"
+    show-force-update-button="applicationState.endpoint.apiVersion >= 1.25"
     ></services-datatable>
   </div>
 </div>
diff --git a/app/components/services/servicesController.js b/app/components/services/servicesController.js
index e2223da48..8937fa392 100644
--- a/app/components/services/servicesController.js
+++ b/app/components/services/servicesController.js
@@ -17,6 +17,39 @@ function ($q, $scope, $state, Service, ServiceService, ServiceHelper, Notificati
     });
   };
 
+  $scope.forceUpdateAction = function(selectedItems) {
+    ModalService.confirmServiceForceUpdate(
+      'Do you want to force update of selected service(s)? All the tasks associated to the selected service(s) will be recreated.',
+      function onConfirm(confirmed) {
+        if(!confirmed) { return; }
+        forceUpdateServices(selectedItems);
+      }
+    );
+  };
+
+  function forceUpdateServices(services) {
+    var actionCount = services.length;
+    angular.forEach(services, function (service) {
+      var config = ServiceHelper.serviceToConfig(service.Model);
+      // As explained in https://github.com/docker/swarmkit/issues/2364 ForceUpdate can accept a random
+      // value or an increment of the counter value to force an update.
+      config.TaskTemplate.ForceUpdate++;
+      ServiceService.update(service, config)
+      .then(function success(data) {
+        Notifications.success('Service successfully updated', service.Name);
+      })
+      .catch(function error(err) {
+        Notifications.error('Failure', err, 'Unable to force update service', service.Name);
+      })
+      .finally(function final() {
+        --actionCount;
+        if (actionCount === 0) {
+          $state.reload();
+        }
+      });
+    });
+  }
+
   $scope.removeAction = function(selectedItems) {
     ModalService.confirmDeletion(
       'Do you want to remove the selected service(s)? All the containers associated to the selected service(s) will be removed too.',
diff --git a/app/directives/ui/datatables/services-datatable/servicesDatatable.html b/app/directives/ui/datatables/services-datatable/servicesDatatable.html
index 60afade12..bd458edd2 100644
--- a/app/directives/ui/datatables/services-datatable/servicesDatatable.html
+++ b/app/directives/ui/datatables/services-datatable/servicesDatatable.html
@@ -16,6 +16,10 @@
           ng-disabled="$ctrl.state.selectedItemCount === 0" ng-click="$ctrl.removeAction($ctrl.state.selectedItems)">
           <i class="fa fa-trash space-right" aria-hidden="true"></i>Remove
         </button>
+        <button ng-if="$ctrl.showForceUpdateButton" type="button" class="btn btn-sm btn-primary"
+          ng-disabled="$ctrl.state.selectedItemCount === 0" ng-click="$ctrl.forceUpdateAction($ctrl.state.selectedItems)">
+          <i class="fa fa-refresh space-right" aria-hidden="true"></i>Force update
+        </button>
         <button type="button" class="btn btn-sm btn-primary" ui-sref="actions.create.service">
           <i class="fa fa-plus space-right" aria-hidden="true"></i>Add service
         </button>
diff --git a/app/directives/ui/datatables/services-datatable/servicesDatatable.js b/app/directives/ui/datatables/services-datatable/servicesDatatable.js
index 14ae8954c..9d33fea66 100644
--- a/app/directives/ui/datatables/services-datatable/servicesDatatable.js
+++ b/app/directives/ui/datatables/services-datatable/servicesDatatable.js
@@ -12,6 +12,8 @@ angular.module('ui').component('servicesDatatable', {
     showOwnershipColumn: '<',
     removeAction: '<',
     scaleAction: '<',
-    swarmManagerIp: '<'
+    swarmManagerIp: '<',
+    forceUpdateAction: '<',
+    showForceUpdateButton: '<'
   }
 });
diff --git a/app/services/modalService.js b/app/services/modalService.js
index 81b0b84a9..4c81bdcc6 100644
--- a/app/services/modalService.js
+++ b/app/services/modalService.js
@@ -156,5 +156,19 @@ angular.module('portainer.services')
     });
   };
 
+  service.confirmServiceForceUpdate = function(message, callback) {
+    service.confirm({
+      title: 'Are you sure ?',
+      message: message,
+      buttons: {
+        confirm: {
+          label: 'Update',
+          className: 'btn-primary'
+        }
+      },
+      callback: callback
+    });
+  };
+
   return service;
 }]);