diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php b/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
index 8f4c3a8..5ed2e1f 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
@@ -335,6 +335,12 @@ public function load() {
       'name' => 'syslog_identity',
       'value' => 's:6:"drupal";',
     ))->values(array(
+      'name' => 'taxonomy_override_selector',
+      'value' => 'b:1;',
+    ))->values(array(
+      'name' => 'taxonomy_terms_per_page_admin',
+      'value' => 'i:84;',
+    ))->values(array(
       'name' => 'theme_default',
       'value' => 's:6:"bartik";',
     ))->values(array(
@@ -449,4 +455,4 @@ public function load() {
   }
 
 }
-#5b6552f715939e2b33c22779e47e73e3
+#01165eaa88fdf782cc2920c4a0727381
diff --git a/core/modules/taxonomy/migration_templates/d7_taxonomy_settings.yml b/core/modules/taxonomy/migration_templates/d7_taxonomy_settings.yml
new file mode 100644
index 0000000..ed8a779
--- /dev/null
+++ b/core/modules/taxonomy/migration_templates/d7_taxonomy_settings.yml
@@ -0,0 +1,15 @@
+id: d7_taxonomy_settings
+label: Drupal 7 taxonomy configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: variable
+  variables:
+    - taxonomy_override_selector
+    - taxonomy_terms_per_page_admin
+process:
+  override_selector: taxonomy_override_selector
+  terms_per_page_admin: taxonomy_terms_per_page_admin
+destination:
+  plugin: config
+  config_name: taxonomy.settings
diff --git a/core/modules/taxonomy/migration_templates/d7_taxonomy_term.yml b/core/modules/taxonomy/migration_templates/d7_taxonomy_term.yml
new file mode 100755
index 0000000..19c2cb4
--- /dev/null
+++ b/core/modules/taxonomy/migration_templates/d7_taxonomy_term.yml
@@ -0,0 +1,28 @@
+id: d7_taxonomy_term
+label: Drupal 7 taxonomy terms
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_taxonomy_term
+process:
+  tid: tid
+  vid:
+    plugin: migration
+    migration: d7_taxonomy_vocabulary
+    source: vid
+  name: name
+  description: description
+  weight: weight
+  parent:
+    -
+      plugin: skip_process_on_empty
+      source: parent
+    -
+      plugin: migration
+      migration: d7_taxonomy_term
+  changed: timestamp
+destination:
+  plugin: entity:taxonomy_term
+migration_dependencies:
+  required:
+    - d7_taxonomy_vocabulary
diff --git a/core/modules/taxonomy/migration_templates/d7_taxonomy_vocabulary.yml b/core/modules/taxonomy/migration_templates/d7_taxonomy_vocabulary.yml
new file mode 100755
index 0000000..065c19a
--- /dev/null
+++ b/core/modules/taxonomy/migration_templates/d7_taxonomy_vocabulary.yml
@@ -0,0 +1,23 @@
+id: d7_taxonomy_vocabulary
+label: Drupal 7 taxonomy vocabularies
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_taxonomy_vocabulary
+process:
+  vid:
+    -
+      plugin: machine_name
+      source: machine_name
+    -
+      plugin: dedupe_entity
+      entity_type: taxonomy_vocabulary
+      field: vid
+      length: 32
+  label: name
+  name: name
+  description: description
+  hierarchy: hierarchy
+  weight: weight
+destination:
+  plugin: entity:taxonomy_vocabulary
diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php
new file mode 100755
index 0000000..6d86f25
--- /dev/null
+++ b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\migrate\source\Term.
+ */
+
+namespace Drupal\taxonomy\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 taxonomy terms source from database.
+ *
+ * @todo Support term_relation, term_synonym table if possible.
+ *
+ * @MigrateSource(
+ *   id = "d7_taxonomy_term",
+ *   source_provider = "taxonomy"
+ * )
+ */
+class Term extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    // Note the explode - this supports the (admittedly unusual) case of
+    // consolidating multiple vocabularies into one.
+    $query = $this->select('taxonomy_term_data', 'td')
+      ->fields('td')
+      ->distinct();
+    if (isset($this->configuration['vocabulary'])) {
+      $query->condition('vid', $this->configuration['vocabulary'], 'IN');
+    }
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'tid' => $this->t('The term ID.'),
+      'vid' => $this->t('Existing term VID'),
+      'name' => $this->t('The name of the term.'),
+      'description' => $this->t('The term description.'),
+      'weight' => $this->t('Weight'),
+      'parent' => $this->t("The Drupal term IDs of the term's parents."),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    // Find parents for this row.
+    $parents = $this->select('taxonomy_term_hierarchy', 'th')
+      ->fields('th', array('parent', 'tid'))
+      ->condition('tid', $row->getSourceProperty('tid'))
+      ->execute()
+      ->fetchCol();
+    $row->setSourceProperty('parent', $parents);
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['tid']['type'] = 'integer';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Vocabulary.php b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Vocabulary.php
new file mode 100755
index 0000000..dc22070
--- /dev/null
+++ b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Vocabulary.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\migrate\source\Vocabulary.
+ */
+
+namespace Drupal\taxonomy\Plugin\migrate\source\d7;
+
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 vocabularies source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_taxonomy_vocabulary",
+ *   source_provider = "taxonomy"
+ * )
+ */
+class Vocabulary extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = $this->select('taxonomy_vocabulary', 'v')
+      ->fields('v', array(
+        'vid',
+        'name',
+        'description',
+        'hierarchy',
+        'module',
+        'weight',
+        'machine_name'
+      ));
+    $query->condition('vid', array(5, 6), 'NOT IN');
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'vid' => $this->t('The vocabulary ID.'),
+      'name' => $this->t('The name of the vocabulary.'),
+      'description' => $this->t('The description of the vocabulary.'),
+      'help' => $this->t('Help text to display for the vocabulary.'),
+      'relations' => $this->t('Whether or not related terms are enabled within the vocabulary. (0 = disabled, 1 = enabled)'),
+      'hierarchy' => $this->t('The type of hierarchy allowed within the vocabulary. (0 = disabled, 1 = single, 2 = multiple)'),
+      'weight' => $this->t('The weight of the vocabulary in relation to other vocabularies.'),
+      'parents' => $this->t("The Drupal term IDs of the term's parents."),
+      'node_types' => $this->t('The names of the node types the vocabulary may be used with.'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['vid']['type'] = 'integer';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomySettingsTest.php b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomySettingsTest.php
new file mode 100644
index 0000000..c8f077a
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomySettingsTest.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Tests\Migrate\d7\MigrateTaxonomySettingsTest.
+ */
+
+namespace Drupal\taxonomy\Tests\Migrate\d7;
+
+use Drupal\config\Tests\SchemaCheckTestTrait;
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+
+/**
+ * Upgrade variables to taxonomy.settings config object.
+ *
+ * @group taxonomy
+ */
+class MigrateTaxonomySettingsTest extends MigrateDrupal7TestBase {
+
+  use SchemaCheckTestTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('taxonomy');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->loadDumps(['Variable.php']);
+    $this->executeMigration('d7_taxonomy_settings');
+  }
+
+  /**
+   * Tests migration of taxonomy variables to taxonomy.settings.yml.
+   */
+  public function testAggregatorSettings() {
+    $config = $this->config('taxonomy.settings');
+    $this->assertTrue($config->get('override_selector'));
+    $this->assertIdentical(84, $config->get('terms_per_page_admin'));
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyTermTest.php b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyTermTest.php
new file mode 100644
index 0000000..c5b4b1b
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyTermTest.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Tests\Migrate\d7\MigrateTaxonomyTermTest.
+ */
+
+namespace Drupal\taxonomy\Tests\Migrate\d7;
+
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+use Drupal\taxonomy\Entity\Term;
+use Drupal\taxonomy\TermInterface;
+
+/**
+ * Upgrade taxonomy terms.
+ *
+ * @group taxonomy
+ */
+class MigrateTaxonomyTermTest extends MigrateDrupal7TestBase {
+
+  static $modules = array('taxonomy', 'text');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('taxonomy_term');
+
+    $this->prepareMigrations(array(
+      'd7_taxonomy_vocabulary' => array(
+        array(array(1), array('tags')),
+        array(array(2), array('forums')),
+        array(array(3), array('test_vocabulary')),
+    )));
+    $this->loadDumps([
+      'TaxonomyTermData.php',
+      'TaxonomyTermHierarchy.php',
+      'TaxonomyVocabulary.php',
+    ]);
+    $this->executeMigration('d7_taxonomy_term');
+  }
+
+  protected function assertEntity($id, $expected_label, $expected_vid, $expected_description = '', $expected_weight = 0, $expected_parents = []) {
+    /** @var \Drupal\taxonomy\TermInterface $entity */
+    $entity = Term::load($id);
+    $this->assertTrue($entity instanceof TermInterface);
+    $this->assertIdentical($expected_label, $entity->label());
+    $this->assertIdentical($expected_vid, $entity->getVocabularyId());
+    $this->assertEqual($expected_description, $entity->getDescription());
+    $this->assertEqual($expected_weight, $entity->getWeight());
+    $this->assertIdentical($expected_parents, $this->getParentIDs($id));
+  }
+
+  /**
+   * Tests the Drupal 7 taxonomy term to Drupal 8 migration.
+   */
+  public function testTaxonomyTerms() {
+    $this->assertEntity(1, 'General discussion', 'forums', '', 2);
+    $this->assertEntity(2, 'Term1', 'test_vocabulary', 'The first term.');
+    $this->assertEntity(3, 'Term2', 'test_vocabulary', 'The second term.');
+    $this->assertEntity(4, 'Term3', 'test_vocabulary', 'The third term.', 0, [3]);
+    $this->assertEntity(5, 'Custom Forum', 'forums', 'Where the cool kids are.', 3);
+    $this->assertEntity(6, 'Games', 'forums', '', 4);
+    $this->assertEntity(7, 'Minecraft', 'forums', '', 1, [6]);
+    $this->assertEntity(8, 'Half Life 3', 'forums', '', 0, [6]);
+  }
+
+  private function getParentIDs($tid) {
+    return array_keys(\Drupal::entityManager()->getStorage('taxonomy_term')->loadParents($tid));
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyVocabularyTest.php b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyVocabularyTest.php
new file mode 100644
index 0000000..8c748d8
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Migrate/d7/MigrateTaxonomyVocabularyTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Tests\Migrate\d7\MigrateTaxonomyVocabularyTest.
+ */
+
+namespace Drupal\taxonomy\Tests\Migrate\d7;
+
+use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
+use Drupal\taxonomy\Entity\Vocabulary;
+use Drupal\taxonomy\VocabularyInterface;
+
+/**
+ * Migrate taxonomy vocabularies to taxonomy.vocabulary.*.yml.
+ *
+ * @group taxonomy
+ */
+class MigrateTaxonomyVocabularyTest extends MigrateDrupal7TestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('taxonomy');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->loadDumps(['TaxonomyVocabulary.php']);
+    $this->executeMigration('d7_taxonomy_vocabulary');
+  }
+
+  protected function assertEntity($id, $expected_label, $expected_description, $expected_hierarchy, $expected_weight) {
+    /** @var \Drupal\taxonomy\VocabularyInterface $entity */
+    $entity = Vocabulary::load($id);
+    $this->assertTrue($entity instanceof VocabularyInterface);
+    $this->assertIdentical($expected_label, $entity->label());
+    $this->assertIdentical($expected_description, $entity->getDescription());
+    $this->assertIdentical($expected_hierarchy, $entity->getHierarchy());
+    $this->assertIdentical($expected_weight, $entity->get('weight'));
+  }
+
+  /**
+   * Tests the Drupal 7 taxonomy vocabularies to Drupal 8 migration.
+   */
+  public function testTaxonomyVocabulary() {
+    $this->assertEntity('tags', 'Tags', 'Use tags to group articles on similar topics into categories.', TAXONOMY_HIERARCHY_DISABLED, 0);
+    $this->assertEntity('forums', 'Forums', 'Forum navigation vocabulary', TAXONOMY_HIERARCHY_SINGLE, -10);
+    $this->assertEntity('test_vocabulary', 'Test Vocabulary', 'This is the vocabulary description', TAXONOMY_HIERARCHY_SINGLE, 0);
+  }
+
+}
diff --git a/core/modules/taxonomy/tests/src/Unit/Migrate/d7/TermTest.php b/core/modules/taxonomy/tests/src/Unit/Migrate/d7/TermTest.php
new file mode 100644
index 0000000..a4c2ae9
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Unit/Migrate/d7/TermTest.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\taxonomy\Unit\Migrate\d7\TermTestBase.
+ */
+
+namespace Drupal\Tests\taxonomy\Unit\Migrate\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Taxonomy term source unit test.
+ *
+ * @group taxonomy
+ */
+class TermTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\taxonomy\Plugin\migrate\source\d7\Term';
+
+  protected $migrationConfiguration = array(
+    'id' => 'test',
+    'highWaterProperty' => array('field' => 'test'),
+    'idlist' => array(),
+    'source' => array(
+      'plugin' => 'd7_taxonomy_term',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'tid' => 1,
+      'vid' => 5,
+      'name' => 'name value 1',
+      'description' => 'description value 1',
+      'weight' => 0,
+      'parent' => array(0),
+    ),
+    array(
+      'tid' => 2,
+      'vid' => 6,
+      'name' => 'name value 2',
+      'description' => 'description value 2',
+      'weight' => 0,
+      'parent' => array(0),
+    ),
+    array(
+      'tid' => 3,
+      'vid' => 6,
+      'name' => 'name value 3',
+      'description' => 'description value 3',
+      'weight' => 0,
+      'parent' => array(0),
+    ),
+    array(
+      'tid' => 4,
+      'vid' => 5,
+      'name' => 'name value 4',
+      'description' => 'description value 4',
+      'weight' => 1,
+      'parent' => array(1),
+    ),
+    array(
+      'tid' => 5,
+      'vid' => 6,
+      'name' => 'name value 5',
+      'description' => 'description value 5',
+      'weight' => 1,
+      'parent' => array(2),
+    ),
+    array(
+      'tid' => 6,
+      'vid' => 6,
+      'name' => 'name value 6',
+      'description' => 'description value 6',
+      'weight' => 0,
+      'parent' => array(3, 2),
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    foreach ($this->expectedResults as $k => $row) {
+      foreach ($row['parent'] as $parent) {
+        $this->databaseContents['taxonomy_term_hierarchy'][] = array(
+          'tid' => $row['tid'],
+          'parent' => $parent,
+        );
+      }
+      unset($row['parent']);
+      $this->databaseContents['taxonomy_term_data'][$k] = $row;
+    }
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/taxonomy/tests/src/Unit/Migrate/d7/VocabularyTest.php b/core/modules/taxonomy/tests/src/Unit/Migrate/d7/VocabularyTest.php
new file mode 100644
index 0000000..27e6f2d
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Unit/Migrate/d7/VocabularyTest.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\taxonomy\Unit\Migrate\d7\VocabularyTest.
+ */
+
+namespace Drupal\Tests\taxonomy\Unit\Migrate\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D6 vocabulary source plugin.
+ *
+ * @group taxonomy
+ */
+class VocabularyTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\taxonomy\Plugin\migrate\source\d7\Vocabulary';
+
+  // The fake Migration configuration entity.
+  protected $migrationConfiguration = array(
+    // The ID of the entity, can be any string.
+    'id' => 'test',
+    // Leave it empty for now.
+    'idlist' => array(),
+    'source' => array(
+      'plugin' => 'd7_vocabulary',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      'vid' => 1,
+      'name' => 'Tags',
+      'machine_name' => 'tags',
+      'description' => 'Tags description.',
+      'hierarchy' => 0,
+      'module' => 'taxonomy',
+      'weight' => 0,
+    ),
+    array(
+      'vid' => 2,
+      'name' => 'Categories',
+      'machine_name' => 'categories',
+      'description' => 'Categories description.',
+      'hierarchy' => 1,
+      'module' => 'taxonomy',
+      'weight' => 0,
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $this->databaseContents['taxonomy_vocabulary'] = $this->expectedResults;
+    parent::setUp();
+  }
+
+}
