diff --git a/core/lib/Drupal/Core/Action/ActionBase.php b/core/lib/Drupal/Core/Action/ActionBase.php
index 9278deb..57023a8 100644
--- a/core/lib/Drupal/Core/Action/ActionBase.php
+++ b/core/lib/Drupal/Core/Action/ActionBase.php
@@ -28,4 +28,11 @@ public function executeMultiple(array $entities) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getLabelArguments() {
+    return [];
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Action/ActionInterface.php b/core/lib/Drupal/Core/Action/ActionInterface.php
index ab9514c..61c39a4 100644
--- a/core/lib/Drupal/Core/Action/ActionInterface.php
+++ b/core/lib/Drupal/Core/Action/ActionInterface.php
@@ -63,4 +63,11 @@ public function executeMultiple(array $objects);
    */
   public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE);
 
+  /**
+   * Arguments for FormattableMarkup for a the label.
+   *
+   * @return string[]
+   */
+  public function getLabelArguments();
+
 }
diff --git a/core/modules/action/src/ActionFormBase.php b/core/modules/action/src/ActionFormBase.php
index 0b972d4..7fb3df6 100644
--- a/core/modules/action/src/ActionFormBase.php
+++ b/core/modules/action/src/ActionFormBase.php
@@ -91,7 +91,7 @@ public function form(array $form, FormStateInterface $form_state) {
     );
 
     if ($this->plugin instanceof PluginFormInterface) {
-      $form += $this->plugin->buildConfigurationForm($form, $form_state);
+      $form = $this->plugin->buildConfigurationForm($form, $form_state);
     }
 
     return parent::form($form, $form_state);
diff --git a/core/modules/simpletest/src/AssertContentTrait.php b/core/modules/simpletest/src/AssertContentTrait.php
index 3d27687..1ccdbf5 100644
--- a/core/modules/simpletest/src/AssertContentTrait.php
+++ b/core/modules/simpletest/src/AssertContentTrait.php
@@ -527,6 +527,18 @@ protected function assertNoEscaped($raw, $message = '', $group = 'Other') {
     return $this->assert(strpos($this->getRawContent(), Html::escape($raw)) === FALSE, $message, $group);
   }
 
+
+  /**
+   * Temporary assert.
+   * @param $raw
+   * @param $out
+   * @return mixed
+   */
+  protected function assertNotEscaped($raw, $out) {
+    $message = 'ESCAPÉ "' . Html::escape($raw) . '" NOT FOUND';
+    return $this->assert(strpos($out, Html::escape($raw)) === FALSE, $message, $group = 'Other');
+  }
+
   /**
    * Passes if the page (with HTML stripped) contains the text.
    *
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 4de845d..e4cb3ea 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -1542,6 +1542,8 @@ protected function drupalGet($path, array $options = array(), array $headers = a
     $verbose .= '<hr />' . $out;
 
     $this->verbose($verbose);
+    $this->assertNoEscaped('&lt;', $out);
+    $this->assertNoEscaped('&amp;', $out);
     return $out;
   }
 
@@ -1775,6 +1777,8 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array(
           $verbose .= '<hr />' . $out;
 
           $this->verbose($verbose);
+          $this->assertNotEscaped('&lt;', $out);
+          $this->assertNotEscaped('&amp;', $out);
           return $out;
         }
       }
@@ -2078,7 +2082,7 @@ protected function drupalProcessAjaxResponse($content, array $ajax_response, arr
    * @see WebTestBase::curlExec()
    */
   protected function drupalPost($path, $accept, array $post, $options = array()) {
-    return $this->curlExec(array(
+    $out = $this->curlExec(array(
       CURLOPT_URL => $this->buildUrl($path, $options),
       CURLOPT_POST => TRUE,
       CURLOPT_POSTFIELDS => $this->serializePostValues($post),
@@ -2087,6 +2091,10 @@ protected function drupalPost($path, $accept, array $post, $options = array()) {
         'Content-Type: application/x-www-form-urlencoded',
       ),
     ));
+
+    $this->assertNotEscaped('&lt;', $out);
+    $this->assertNotEscaped('&amp;', $out);
+    return $out;
   }
 
   /**
diff --git a/core/modules/system/src/Entity/Action.php b/core/modules/system/src/Entity/Action.php
index b5a0f19..3fbc6e1 100644
--- a/core/modules/system/src/Entity/Action.php
+++ b/core/modules/system/src/Entity/Action.php
@@ -7,8 +7,11 @@
 
 namespace Drupal\system\Entity;
 
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Component\Render\PlainTextOutput;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
 use Drupal\system\ActionConfigEntityInterface;
 use Drupal\Core\Action\ActionPluginCollection;
@@ -86,6 +89,7 @@ class Action extends ConfigEntityBase implements ActionConfigEntityInterface, En
    */
   protected function getPluginCollection() {
     if (!$this->pluginCollection) {
+      $this->configuration['original_label'] = parent::label();
       $this->pluginCollection = new ActionPluginCollection(\Drupal::service('plugin.manager.action'), $this->plugin, $this->configuration);
     }
     return $this->pluginCollection;
@@ -155,4 +159,24 @@ public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b)
     return parent::sort($a, $b);
   }
 
+  /**
+   * @inheritDoc
+   */
+  public function label() {
+    $plugin = $this->getPlugin();
+    $label = new FormattableMarkup(parent::label(), $plugin->getLabelArguments());
+    // Remove the safeness from the label as the label can contain user input.
+    return PlainTextOutput::renderFromHtml($label);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave(EntityStorageInterface $storage) {
+    parent::preSave($storage);
+    // Remove original label when saving so as this does not need to be stored
+    // in configuration.
+    unset($this->configuration['original_label']);
+  }
+
 }
diff --git a/core/modules/system/src/Plugin/views/field/BulkForm.php b/core/modules/system/src/Plugin/views/field/BulkForm.php
index 3a3b65c..1ae8236 100644
--- a/core/modules/system/src/Plugin/views/field/BulkForm.php
+++ b/core/modules/system/src/Plugin/views/field/BulkForm.php
@@ -292,7 +292,9 @@ public function viewsForm(&$form, FormStateInterface $form_state) {
       $form['header'][$this->options['id']]['action'] = array(
         '#type' => 'select',
         '#title' => $this->options['action_title'],
-        '#options' => $this->getBulkOptions(),
+        // This is a select list therefore apply the plain text formatter to the
+        // the options which are escaped for display in HTML.
+        '#options' =>  array_map('\Drupal\Component\Render\PlainTextOutput::renderFromHtml', $this->getBulkOptions()),
       );
 
       // Duplicate the form actions into the action container in the header.
diff --git a/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php b/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php
index 12353b3..3f17fb9 100644
--- a/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php
+++ b/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php
@@ -14,6 +14,7 @@
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\user\RoleInterface;
+use Drupal\user\RoleStorageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -31,11 +32,19 @@
   protected $entityType;
 
   /**
+   * The user role storage.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeInterface
+   */
+  protected $roleStorage;
+
+  /**
    * {@inheritdoc}
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeInterface $entity_type) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeInterface $entity_type, RoleStorageInterface $role_storage) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->entityType = $entity_type;
+    $this->roleStorage = $role_storage;
   }
 
   /**
@@ -46,7 +55,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('entity.manager')->getDefinition('user_role')
+      $container->get('entity.manager')->getDefinition('user_role'),
+      $container->get('entity.manager')->getStorage('user_role')
     );
   }
 
@@ -63,6 +73,14 @@ public function defaultConfiguration() {
    * {@inheritdoc}
    */
   public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    // The label supports replacing @label with the role's label.
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => $this->t('Label'),
+      '#default_value' => $this->configuration['original_label'],
+      '#maxlength' => '255',
+      '#description' => $this->t('A unique label for this advanced action. This label will be displayed in the interface of modules that integrate with actions. @role_label is replaced with the role\'s label.'),
+    );
     $roles = user_role_names(TRUE);
     unset($roles[RoleInterface::AUTHENTICATED_ID]);
     $form['rid'] = array(
@@ -104,4 +122,15 @@ public function access($object, AccountInterface $account = NULL, $return_as_obj
     return $return_as_object ? $access : $access->isAllowed();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getLabelArguments() {
+    if (!empty($this->configuration['rid'])) {
+      $role = $this->roleStorage->load($this->configuration['rid']);
+      return ['@role_label' => $role->label()];
+    }
+    return [];
+  }
+
 }
diff --git a/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php b/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php
index a2f9e9c..c408ba4 100644
--- a/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php
+++ b/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php
@@ -28,7 +28,7 @@ public function testExecuteAddExistingRole() {
       ->will($this->returnValue(TRUE));
 
     $config = array('rid' => 'test_role_1');
-    $remove_role_plugin = new AddRoleUser($config, 'user_add_role_action', array('type' => 'user'), $this->userRoleEntityType);
+    $remove_role_plugin = new AddRoleUser($config, 'user_add_role_action', array('type' => 'user'), $this->userRoleEntityType, $this->roleStorage);
 
     $remove_role_plugin->execute($this->account);
   }
@@ -46,7 +46,7 @@ public function testExecuteAddNonExistingRole() {
       ->will($this->returnValue(FALSE));
 
     $config = array('rid' => 'test_role_1');
-    $remove_role_plugin = new AddRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType);
+    $remove_role_plugin = new AddRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType, $this->roleStorage);
 
     $remove_role_plugin->execute($this->account);
   }
diff --git a/core/modules/user/tests/src/Unit/Plugin/Action/RoleUserTestBase.php b/core/modules/user/tests/src/Unit/Plugin/Action/RoleUserTestBase.php
index 5f7ff13..104f1b6 100644
--- a/core/modules/user/tests/src/Unit/Plugin/Action/RoleUserTestBase.php
+++ b/core/modules/user/tests/src/Unit/Plugin/Action/RoleUserTestBase.php
@@ -8,6 +8,7 @@
 namespace Drupal\Tests\user\Unit\Plugin\Action;
 
 use Drupal\Tests\UnitTestCase;
+use Drupal\user\RoleStorageInterface;
 
 /**
  * Provides a base class for user role action tests.
@@ -29,6 +30,13 @@
   protected $userRoleEntityType;
 
   /**
+   * The role storage.
+   *
+   * @var \Drupal\user\RoleStorageInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $roleStorage;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -39,6 +47,7 @@ protected function setUp() {
       ->disableOriginalConstructor()
       ->getMock();
     $this->userRoleEntityType = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
+    $this->roleStorage = $this->getMock(RoleStorageInterface::class);
   }
 
 }
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 3b80af6..29550c0 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -988,7 +988,7 @@ function user_user_role_insert(RoleInterface $role) {
     $action = entity_create('action', array(
       'id' => $add_id,
       'type' => 'user',
-      'label' => t('Add the @label role to the selected users', array('@label' => $role->label())),
+      'label' => t('Add the @role_label role to the selected users'),
       'configuration' => array(
         'rid' => $role->id(),
       ),
@@ -1001,7 +1001,7 @@ function user_user_role_insert(RoleInterface $role) {
     $action = entity_create('action', array(
       'id' => $remove_id,
       'type' => 'user',
-      'label' => t('Remove the @label role from the selected users', array('@label' => $role->label())),
+      'label' => t('Remove the @role_label role from the selected users'),
       'configuration' => array(
         'rid' => $role->id(),
       ),
