diff --git a/core/modules/migrate/config/schema/migrate.data_types.schema.yml b/core/modules/migrate/config/schema/migrate.data_types.schema.yml
index edb628a..d887785 100644
--- a/core/modules/migrate/config/schema/migrate.data_types.schema.yml
+++ b/core/modules/migrate/config/schema/migrate.data_types.schema.yml
@@ -14,6 +14,10 @@ migrate_destination:
 migrate_source:
   type: migrate_plugin
   label: 'Source'
+  mapping:
+    constants:
+      type: ignore
+      label: 'Constants'
 
 # Base schema for migrate source plugins that extend
 # \Drupal\migrate\Plugin\migrate\source\SqlBase.
diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d7_node_type.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d7_node_type.yml
new file mode 100644
index 0000000..c0b8332
--- /dev/null
+++ b/core/modules/migrate_drupal/config/install/migrate.migration.d7_node_type.yml
@@ -0,0 +1,24 @@
+id: d7_node_type
+label: Drupal 7 node type configuration
+migration_groups:
+  - Drupal 7
+source:
+  plugin: d7_node_type
+  constants:
+    preview: 1 # DRUPAL_OPTIONAL
+    has_body: 1 # DRUPAL_OPTION
+process:
+  type: type
+  name: name
+  module: module
+  description: description
+  help: help
+  title_label: title_label
+  'preview_mode': 'constants/preview'
+  'display_submitted': display_submitted
+  'new_revision': 'options/revision'
+  'settings/node/options': options
+  create_body: 'constants/has_body'
+  create_body_label: body_label
+destination:
+  plugin: entity:node_type
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/NodeType.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/NodeType.php
new file mode 100644
index 0000000..5f34f79
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/NodeType.php
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Plugin\migrate\source\d7\NodeType.
+ */
+
+namespace Drupal\migrate_drupal\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 7 Node types source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_node_type"
+ * )
+ */
+class NodeType extends DrupalSqlBase {
+
+  /**
+   * The teaser length
+   *
+   * @var int
+   */
+  protected $teaserLength;
+
+  /**
+   * Node preview optional / required.
+   *
+   * @var int
+   */
+  protected $nodePreview;
+
+  /**
+   * An array of theme settings.
+   *
+   * @var array
+   */
+  protected $themeSettings;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('node_type', 't')
+      ->fields('t', array(
+        'type',
+        'name',
+        'module',
+        'description',
+        'help',
+        'title_label',
+        'disabled',
+        'base',
+        'custom',
+        'modified',
+        'locked',
+        'orig_type',
+      ))
+      ->orderBy('t.type');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'type' => $this->t('Machine name of the node type.'),
+      'name' => $this->t('Human name of the node type.'),
+      'module' => $this->t('The module providing the node type.'),
+      'description' => $this->t('Description of the node type.'),
+      'help' => $this->t('Help text for the node type.'),
+      'title_label' => $this->t('Title label.'),
+      'disabled' => $this->t('Flag indicating the node type is enable'),
+      'base' => $this->t('base node.'),
+      'custom' => $this->t('Flag.'),
+      'modified' => $this->t('Flag.'),
+      'locked' => $this->t('Flag.'),
+      'orig_type' => $this->t('The original type.'),
+      'teaser_length' => $this->t('Teaser length'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function runQuery() {
+    $this->teaserLength = $this->variableGet('teaser_length', 600);
+    $this->nodePreview = $this->variableGet('node_preview', 0);
+    $this->themeSettings = $this->variableGet('theme_settings', array());
+    return parent::runQuery();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+
+    $row->setSourceProperty('teaser_length', $this->teaserLength);
+    $row->setSourceProperty('node_preview', $this->nodePreview);
+
+    $type = $row->getSourceProperty('type');
+    $source_options = $this->variableGet('node_options_' . $type, array('promote', 'sticky'));
+    $options = array();
+    foreach (array('promote', 'sticky', 'status', 'revision') as $item) {
+      $options[$item] = in_array($item, $source_options);
+    }
+    // Find body for  for this row.
+    $query = $this->select('field_config_instance', 'fci')
+      ->fields('fci', array('data'))
+      ->condition('bundle', $row->getSourceProperty('type'))
+      ->condition('field_name', 'body')
+      ->execute()
+      ->fetchAssoc();
+
+    $body_data = unserialize($query['data']);
+    $body_label = $body_data['label'];
+
+    $row->setSourceProperty('options', $options);
+    $submitted = isset($this->themeSettings['toggle_node_info_' . $type]) ? $this->themeSettings['toggle_node_info_' . $type] : FALSE;
+    $row->setSourceProperty('display_submitted', $submitted);
+    $row->setSourceProperty('body_label', $body_label);
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['type']['type'] = 'string';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateNodeTypeTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateNodeTypeTest.php
new file mode 100644
index 0000000..02273d8
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateNodeTypeTest.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateNodeTypeTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\migrate\MigrateExecutable;
+use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
+use Drupal\node\Entity\NodeType;
+use Drupal\node\NodeTypeInterface;
+
+/**
+ * Upgrade node types to node.type.*.yml.
+ *
+ * @group migrate_drupal 7.x
+ * @dumpFile d7/FieldConfig.php
+ * @dumpFile d7/FieldConfigInstance.php
+ * @dumpFile d7/NodeType.php
+ * @dumpFile d7/Variable.php
+ */
+class MigrateNodeTypeTest extends MigrateDrupalTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('node', 'text', 'filter');
+
+  protected function getDumpDirectory() {
+    return parent::getDumpDirectory() . '/d7';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installConfig(array('node'));
+
+    $migration = entity_load('migration', 'd7_node_type');
+    $dumps = array(
+      $this->getDumpDirectory() . '/FieldConfig.php',
+      $this->getDumpDirectory() . '/FieldConfigInstance.php',
+      $this->getDumpDirectory() . '/NodeType.php',
+      $this->getDumpDirectory() . '/Variable.php',
+    );
+    $this->prepare($migration, $dumps);
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  protected function assertEntity($id, $label, $description) {
+    /** @var \Drupal\node\NodeTypeInterface $entity */
+    $entity = NodeType::load($id);
+    $this->assertTrue($entity instanceof NodeTypeInterface);
+    $this->assertIdentical($label, $entity->label());
+    $this->assertIdentical($description, $entity->getDescription());
+  }
+
+  /**
+   * Tests Drupal 7 node type to Drupal 8 migration.
+   */
+  public function testNodeType() {
+    $this->assertEntity('article', 'Article', 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.');
+    $this->assertEntity('blog', 'Blog entry', 'Use for multi-user blogs. Every user gets a personal blog.');
+    $this->assertEntity('book', 'Book page', '<em>Books</em> have a built-in hierarchical navigation. Use for handbooks or tutorials.');
+    $this->assertEntity('forum', 'Forum topic', 'A <em>forum topic</em> starts a new discussion thread within a forum.');
+    $this->assertEntity('page', 'Basic page', "Use <em>basic pages</em> for your static content, such as an 'About us' page.");
+    $this->assertEntity('test_content_type', 'Test content type', 'This is the description of the test content type.');
+  }
+
+}
