diff --git a/core/modules/action/migration_templates/d6_action.yml b/core/modules/action/migration_templates/d6_action.yml
new file mode 100644
index 0000000000000000000000000000000000000000..592ed1805d9ad323398979d91cdd775f990a7b23
--- /dev/null
+++ b/core/modules/action/migration_templates/d6_action.yml
@@ -0,0 +1,39 @@
+id: d6_action
+label: Actions
+migration_tags:
+  - Drupal 6
+source:
+  plugin: action
+process:
+  id:
+    -
+      plugin: machine_name
+      source: aid
+  label: description
+  type: type
+  plugin:
+    -
+      plugin: static_map
+      source: callback
+      map:
+        system_goto_action: action_goto_action
+        system_send_email_action: action_send_email_action
+        system_message_action: action_message_action
+        user_block_ip_action: 0
+        imagecache_flush_action: 0
+        imagecache_generate_all_action: 0
+        imagecache_generate_action: 0
+      bypass: true
+    -
+      plugin: skip_on_empty
+      method: row
+  configuration:
+    -
+      plugin: default_value
+      source: parameters
+      default_value: "a:0:{}"
+    -
+      plugin: callback
+      callable: unserialize
+destination:
+  plugin: entity:action
diff --git a/core/modules/action/migration_templates/d7_action.yml b/core/modules/action/migration_templates/d7_action.yml
new file mode 100644
index 0000000000000000000000000000000000000000..03b869af183530ecb9aed977dec0dfc8cd22cfa2
--- /dev/null
+++ b/core/modules/action/migration_templates/d7_action.yml
@@ -0,0 +1,36 @@
+id: d7_action
+label: Actions
+migration_tags:
+  - Drupal 7
+source:
+  plugin: action
+process:
+  id:
+    -
+      plugin: machine_name
+      source: aid
+  label: label
+  type: type
+  plugin:
+    -
+      plugin: static_map
+      source: callback
+      map:
+        system_goto_action: action_goto_action
+        system_send_email_action: action_send_email_action
+        system_message_action: action_message_action
+        system_block_ip_action: 0
+      bypass: true
+    -
+      plugin: skip_on_empty
+      method: row
+  configuration:
+    -
+      plugin: default_value
+      source: parameters
+      default_value: "a:0:{}"
+    -
+      plugin: callback
+      callable: unserialize
+destination:
+  plugin: entity:action
diff --git a/core/modules/action/src/Plugin/migrate/source/Action.php b/core/modules/action/src/Plugin/migrate/source/Action.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9cb2c71976b1f8ac3f72df36a89d34bfdc5ec52
--- /dev/null
+++ b/core/modules/action/src/Plugin/migrate/source/Action.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\action\Plugin\migrate\source\Action.
+ */
+
+namespace Drupal\action\Plugin\migrate\source;
+
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+use Drupal\migrate\Row;
+
+/**
+ * Drupal action source from database.
+ *
+ * @MigrateSource(
+ *   id = "action",
+ *   source_provider = "system"
+ * )
+ */
+class Action extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('actions', 'a')
+      ->fields('a');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    $fields = array(
+      'aid' => $this->t('Action ID'),
+      'type' => $this->t('Module'),
+      'callback' => $this->t('Callback function'),
+      'parameters' => $this->t('Action configuration'),
+    );
+    if ($this->getModuleSchemaVersion('system') >= 7000) {
+      $fields['label'] = $this->t('Label of the action');
+    }
+    else {
+      $fields['description'] = $this->t('Action description');
+    }
+    return $fields;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['aid']['type'] = 'string';
+    return $ids;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $aid = $row->getSourceProperty('aid');
+    if (is_numeric($aid)) {
+      if ($this->getModuleSchemaVersion('system') >= 7000) {
+        $label = $row->getSourceProperty('label');
+      }
+      else {
+        $label = $row->getSourceProperty('description');
+      }
+      $row->setSourceProperty('aid', $label);
+    }
+  }
+
+}
diff --git a/core/modules/action/src/Plugin/migrate/source/d6/Action.php b/core/modules/action/src/Plugin/migrate/source/d6/Action.php
deleted file mode 100644
index 2ca7741173da32b09301bdc4536fa2fed6159d86..0000000000000000000000000000000000000000
--- a/core/modules/action/src/Plugin/migrate/source/d6/Action.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\action\Plugin\migrate\source\d6\Action.
- */
-
-namespace Drupal\action\Plugin\migrate\source\d6;
-
-use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
-
-/**
- * Drupal 6 action source from database.
- *
- * @MigrateSource(
- *   id = "d6_action"
- * )
- */
-class Action extends DrupalSqlBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-    $query = $this->select('actions', 'a')
-      ->fields('a', array(
-        'aid',
-        'type',
-        'callback',
-        'parameters',
-        'description',
-      )
-    );
-    return $query;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function fields() {
-    return array(
-      'aid' => $this->t('Action ID'),
-      'type' => $this->t('Module'),
-      'callback' => $this->t('Callback function'),
-      'parameters' => $this->t('Action configuration'),
-      'description' => $this->t('Action description'),
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getIds() {
-    $ids['aid']['type'] = 'string';
-    return $ids;
-  }
-
-}
diff --git a/core/modules/action/src/Tests/Migrate/d6/MigrateActionsTest.php b/core/modules/action/src/Tests/Migrate/d6/MigrateActionsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c37a9a771671068a6c7266ce6ece9430600a137a
--- /dev/null
+++ b/core/modules/action/src/Tests/Migrate/d6/MigrateActionsTest.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\action\Tests\Migrate\d6\MigrateActionsTest.
+ */
+
+namespace Drupal\action\Tests\Migrate\d6;
+
+use Drupal\system\Entity\Action;
+use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
+
+/**
+ * Tests migration of action items.
+ *
+ * @group migrate_drupal_6
+ */
+class MigrateActionsTest extends MigrateDrupal6TestBase {
+
+  public static $modules = ['action', 'comment', 'node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->executeMigration('d6_action');
+  }
+
+  /**
+   * Test Drupal 6 action migration to Drupal 8.
+   */
+  public function testActions() {
+    // Test default actions.
+    $this->assertEntity('node_publish_action', 'Publish post', 'node', []);
+    $this->assertEntity('node_make_sticky_action', 'Make post sticky', 'node', []);
+    $this->assertEntity('user_block_user_action', 'Block current user', 'user', []);
+    $this->assertEntity('comment_publish_action', 'Publish comment', 'comment', []);
+
+    // Test advanced actions.
+    $this->assertEntity('unpublish_comment_containing_keyword_s_', 'Unpublish comment containing keyword(s)', 'comment', ["keywords" => [0 => "drupal"]]);
+    $this->assertEntity('change_the_author_of_a_post', 'Change the author of a post', 'node', ["owner_uid" => "2"]);
+    $this->assertEntity('unpublish_post_containing_keyword_s_', 'Unpublish post containing keyword(s)', 'node', ["keywords" => [0 => "drupal"]]);
+    $this->assertEntity('display_a_message_to_the_user', 'Display a message to the user', 'system', ["message" => "Drupal migration test"]);
+    $this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
+      "recipient" => "test@example.com",
+      "subject" => "Drupal migration test",
+      "message" => "Drupal migration test"
+    ]);
+    $this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);
+
+  }
+
+  /**
+   * Asserts various aspects of an Action entity.
+   *
+   * @param string $id
+   *   The expected Action ID.
+   * @param string $label
+   *   The expected Action label.
+   * @param string $type
+   *   The expected Action type.
+   * @param array $configuration
+   *   The expected Action configuration.
+   */
+  protected function assertEntity($id, $label, $type, $configuration) {
+    $action = Action::load($id);
+
+    $this->assertTrue($action instanceof Action);
+    /** @var \Drupal\system\Entity\Action $action */
+    $this->assertIdentical($id, $action->id());
+    $this->assertIdentical($label, $action->label());
+    $this->assertIdentical($type, $action->getType());
+    $this->assertIdentical($configuration, $action->get('configuration'));
+  }
+
+}
diff --git a/core/modules/action/src/Tests/Migrate/d7/MigrateActionsTest.php b/core/modules/action/src/Tests/Migrate/d7/MigrateActionsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d5421901d79b3b505a19d2c77a9898b1e1cfb28
--- /dev/null
+++ b/core/modules/action/src/Tests/Migrate/d7/MigrateActionsTest.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\action\Tests\Migrate\d7\MigrateActionsTest.
+ */
+
+namespace Drupal\action\Tests\Migrate\d7;
+
+use Drupal\system\Entity\Action;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Tests migration of action items.
+ *
+ * @group action
+ */
+class MigrateActionsTest extends MigrateDrupal7TestBase {
+
+  public static $modules = ['action', 'comment', 'node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->executeMigration('d7_action');
+  }
+
+  /**
+   * Test Drupal 7 action migration to Drupal 8.
+   */
+  public function testActions() {
+    // Test default actions.
+    $this->assertEntity('node_publish_action', 'Publish content', 'node', []);
+    $this->assertEntity('node_make_sticky_action', 'Make content sticky', 'node', []);
+    $this->assertEntity('user_block_user_action', 'Block current user', 'user', []);
+    $this->assertEntity('comment_publish_action', 'Publish comment', 'comment', []);
+
+    // Test advanced actions.
+    $this->assertEntity('unpublish_comment_containing_keyword_s_', 'Unpublish comment containing keyword(s)', 'comment', ["keywords" => [0 => "drupal"]]);
+    $this->assertEntity('change_the_author_of_content', 'Change the author of content', 'node', ["owner_uid" => "2"]);
+    $this->assertEntity('unpublish_content_containing_keyword_s_', 'Unpublish content containing keyword(s)', 'node', ["keywords" => [0 => "drupal"]]);
+    $this->assertEntity('display_a_message_to_the_user', 'Display a message to the user', 'system', ["message" => "Drupal migration test"]);
+    $this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
+      "recipient" => "test@example.com",
+      "subject" => "Drupal migration test",
+      "message" => "Drupal migration test"
+    ]);
+    $this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);
+
+  }
+
+  /**
+   * Asserts various aspects of an Action entity.
+   *
+   * @param string $id
+   *   The expected Action ID.
+   * @param string $label
+   *   The expected Action label.
+   * @param string $type
+   *   The expected Action type.
+   * @param array $configuration
+   *   The expected Action configuration.
+   */
+  protected function assertEntity($id, $label, $type, $configuration) {
+    $action = Action::load($id);
+
+    $this->assertTrue($action instanceof Action);
+    /** @var \Drupal\system\Entity\Action $action */
+    $this->assertIdentical($id, $action->id());
+    $this->assertIdentical($label, $action->label());
+    $this->assertIdentical($type, $action->getType());
+    $this->assertIdentical($configuration, $action->get('configuration'));
+  }
+
+}
diff --git a/core/modules/action/tests/src/Unit/Plugin/migrate/source/d6/ActionTest.php b/core/modules/action/tests/src/Unit/Plugin/migrate/source/ActionTest.php
similarity index 76%
rename from core/modules/action/tests/src/Unit/Plugin/migrate/source/d6/ActionTest.php
rename to core/modules/action/tests/src/Unit/Plugin/migrate/source/ActionTest.php
index 148865aa2cd10bed64fe2b81fff930ceb01494da..44b8fbad3428545f1a0821ac08d1fca3a9c473a7 100644
--- a/core/modules/action/tests/src/Unit/Plugin/migrate/source/d6/ActionTest.php
+++ b/core/modules/action/tests/src/Unit/Plugin/migrate/source/ActionTest.php
@@ -2,15 +2,15 @@
 
 /**
  * @file
- * Contains \Drupal\Tests\action\Unit\Plugin\migrate\source\d6\ActionTest.
+ * Contains \Drupal\Tests\action\Unit\Plugin\migrate\source\ActionTest.
  */
 
-namespace Drupal\Tests\action\Unit\Plugin\migrate\source\d6;
+namespace Drupal\Tests\action\Unit\Plugin\migrate\source;
 
 use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
 
 /**
- * Tests D6 actions source plugin.
+ * Tests actions source plugin.
  *
  * @group action
  */
@@ -18,14 +18,14 @@ class ActionTest extends MigrateSqlSourceTestCase {
 
   // The plugin system is not working during unit testing so the source plugin
   // class needs to be manually specified.
-  const PLUGIN_CLASS = 'Drupal\action\Plugin\migrate\source\d6\Action';
+  const PLUGIN_CLASS = 'Drupal\action\Plugin\migrate\source\Action';
 
   // The fake Migration configuration entity.
   protected $migrationConfiguration = array(
     // The ID of the entity, can be any string.
     'id' => 'test',
     'source' => array(
-      'plugin' => 'd6_action',
+      'plugin' => 'action',
     ),
   );
 
@@ -33,14 +33,14 @@ class ActionTest extends MigrateSqlSourceTestCase {
 
   protected $expectedResults = array(
     array(
-      'aid' => '1',
+      'aid' => 'Redirect to node list page',
       'type' => 'system',
       'callback' => 'system_goto_action',
       'parameters' => 'a:1:{s:3:"url";s:4:"node";}',
       'description' => 'Redirect to node list page',
     ),
     array(
-      'aid' => '2',
+      'aid' => 'Test notice email',
       'type' => 'system',
       'callback' => 'system_send_email_action',
       'parameters' => 'a:3:{s:9:"recipient";s:7:"%author";s:7:"subject";s:4:"Test";s:7:"message";s:4:"Test',
@@ -50,15 +50,15 @@ class ActionTest extends MigrateSqlSourceTestCase {
       'aid' => 'comment_publish_action',
       'type' => 'comment',
       'callback' => 'comment_publish_action',
-      'parameters' => null,
-      'description' => null,
+      'parameters' => NULL,
+      'description' => NULL,
     ),
     array(
       'aid' => 'node_publish_action',
       'type' => 'comment',
       'callback' => 'node_publish_action',
-      'parameters' => null,
-      'description' => null,
+      'parameters' => NULL,
+      'description' => NULL,
     ),
   );
 
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
index 0f60343a3a0628448b429ee6ece5d564e15a396a..76b3bf6e78032198d2ca3fc96f51f0bf0390afa7 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php
@@ -88,6 +88,48 @@
   'parameters',
   'description',
 ))
+->values(array(
+  'aid' => '1',
+  'type' => 'comment',
+  'callback' => 'comment_unpublish_by_keyword_action',
+  'parameters' => 'a:1:{s:8:"keywords";a:1:{i:0;s:6:"drupal";}}',
+  'description' => 'Unpublish comment containing keyword(s)',
+))
+->values(array(
+  'aid' => '2',
+  'type' => 'node',
+  'callback' => 'node_assign_owner_action',
+  'parameters' => 'a:1:{s:9:"owner_uid";s:1:"2";}',
+  'description' => 'Change the author of a post',
+))
+->values(array(
+  'aid' => '3',
+  'type' => 'node',
+  'callback' => 'node_unpublish_by_keyword_action',
+  'parameters' => 'a:1:{s:8:"keywords";a:1:{i:0;s:6:"drupal";}}',
+  'description' => 'Unpublish post containing keyword(s)',
+))
+->values(array(
+  'aid' => '4',
+  'type' => 'system',
+  'callback' => 'system_message_action',
+  'parameters' => 'a:1:{s:7:"message";s:21:"Drupal migration test";}',
+  'description' => 'Display a message to the user',
+))
+->values(array(
+  'aid' => '5',
+  'type' => 'system',
+  'callback' => 'system_send_email_action',
+  'parameters' => 'a:3:{s:9:"recipient";s:16:"test@example.com";s:7:"subject";s:21:"Drupal migration test";s:7:"message";s:21:"Drupal migration test";}',
+  'description' => 'Send e-mail',
+))
+->values(array(
+  'aid' => '6',
+  'type' => 'system',
+  'callback' => 'system_goto_action',
+  'parameters' => 'a:1:{s:3:"url";s:22:"https://www.drupal.org";}',
+  'description' => 'Redirect to URL',
+))
 ->values(array(
   'aid' => 'comment_publish_action',
   'type' => 'comment',
@@ -196,6 +238,30 @@
   'mysql_character_set' => 'utf8',
 ));
 
+$connection->insert('actions_aid')
+->fields(array(
+  'aid',
+))
+->values(array(
+  'aid' => '1',
+))
+->values(array(
+  'aid' => '2',
+))
+->values(array(
+  'aid' => '3',
+))
+->values(array(
+  'aid' => '4',
+))
+->values(array(
+  'aid' => '5',
+))
+->values(array(
+  'aid' => '6',
+))
+->execute();
+
 $connection->schema()->createTable('aggregator_category', array(
   'fields' => array(
     'cid' => array(
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
index 78651e4bebbeb92b231eff0ef77066cd456f2af4..ef7e2bfc643eb1379766a61075207ce9ffb8553f 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
@@ -417,6 +417,48 @@
   'parameters',
   'label',
 ))
+->values(array(
+  'aid' => '2',
+  'type' => 'comment',
+  'callback' => 'comment_unpublish_by_keyword_action',
+  'parameters' => 'a:1:{s:8:"keywords";a:1:{i:0;s:6:"drupal";}}',
+  'label' => 'Unpublish comment containing keyword(s)',
+))
+->values(array(
+  'aid' => '3',
+  'type' => 'node',
+  'callback' => 'node_assign_owner_action',
+  'parameters' => 'a:1:{s:9:"owner_uid";s:1:"2";}',
+  'label' => 'Change the author of content',
+))
+->values(array(
+  'aid' => '4',
+  'type' => 'node',
+  'callback' => 'node_unpublish_by_keyword_action',
+  'parameters' => 'a:1:{s:8:"keywords";a:1:{i:0;s:6:"drupal";}}',
+  'label' => 'Unpublish content containing keyword(s)',
+))
+->values(array(
+  'aid' => '5',
+  'type' => 'system',
+  'callback' => 'system_message_action',
+  'parameters' => 'a:1:{s:7:"message";s:21:"Drupal migration test";}',
+  'label' => 'Display a message to the user',
+))
+->values(array(
+  'aid' => '6',
+  'type' => 'system',
+  'callback' => 'system_send_email_action',
+  'parameters' => 'a:3:{s:9:"recipient";s:16:"test@example.com";s:7:"subject";s:21:"Drupal migration test";s:7:"message";s:21:"Drupal migration test";}',
+  'label' => 'Send e-mail',
+))
+->values(array(
+  'aid' => '7',
+  'type' => 'system',
+  'callback' => 'system_goto_action',
+  'parameters' => 'a:1:{s:3:"url";s:22:"https://www.drupal.org";}',
+  'label' => 'Redirect to URL',
+))
 ->values(array(
   'aid' => 'comment_publish_action',
   'type' => 'comment',