diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php
index 5e11697..4256d0f 100644
--- a/core/lib/Drupal/Core/Config/ConfigImporter.php
+++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Utility\String;
 use Drupal\Core\Config\Entity\ImportableEntityStorageInterface;
+use Drupal\Core\Config\ConfigEvents;
 use Drupal\Core\DependencyInjection\DependencySerialization;
 use Drupal\Core\Entity\EntityStorageException;
 use Drupal\Core\Lock\LockBackendInterface;
@@ -146,7 +147,7 @@ public function reset() {
    * @return bool
    *   TRUE if there are changes to process and FALSE if not.
    */
-  public function hasUnprocessedChanges($ops = array('delete', 'create', 'update')) {
+  public function hasUnprocessedChanges($ops = array('delete', 'create', 'update', 'rename')) {
     foreach ($ops as $op) {
       if (count($this->getUnprocessed($op))) {
         return TRUE;
@@ -212,7 +213,7 @@ public function import() {
       // to handle dependencies correctly.
       // @todo Implement proper dependency ordering using
       //   https://drupal.org/node/2080823
-      foreach (array('delete', 'create', 'update') as $op) {
+      foreach (array('delete', 'create', 'update', 'rename') as $op) {
         foreach ($this->getUnprocessed($op) as $name) {
           $this->process($op, $name);
         }
@@ -239,6 +240,22 @@ public function validate() {
       if (!$this->storageComparer->validateSiteUuid()) {
         throw new ConfigImporterException('Site UUID in source storage does not match the target storage.');
       }
+      // Validate renames.
+      foreach ($this->getUnprocessed('rename') as $name) {
+        $names = explode('::', $name);
+        $old_name = $names[0];
+        $new_name = $names[1];
+        $old_entity_type_id = $this->configManager->getEntityTypeIdByName($old_name);
+        $new_entity_type_id = $this->configManager->getEntityTypeIdByName($new_name);
+        if ($old_entity_type_id != $new_entity_type_id) {
+          throw new ConfigImporterException(String::format('Entity type mismatch on rename. !old_type not equal to !new_type for existing configuration !old_name and staged configuration !new_name.', array('old_type' => $old_entity_type_id, 'new_type' => $new_entity_type_id, 'old_name' => $old_name, 'new_name' => $new_name)));
+        }
+        // Has to be a configuration entity.
+        if (!$old_entity_type_id) {
+          throw new ConfigImporterException(String::format('Rename operation for simple configuration. Existing configuration !old_name and staged configuration !new_name.', array('old_name' => $old_name, 'new_name' => $new_name)));
+        }
+      }
+
       $this->eventDispatcher->dispatch(ConfigEvents::IMPORT_VALIDATE, new ConfigImporterEvent($this));
       $this->validated = TRUE;
     }
@@ -303,6 +320,10 @@ protected function importConfig($op, $name) {
    *   otherwise.
    */
   protected function importInvokeOwner($op, $name) {
+    // Special case renames because they are hard.
+    if ($op == 'rename') {
+      return $this->importInvokeRename($name);
+    }
     // Validate the configuration object name before importing it.
     // Config::validateName($name);
     if ($entity_type = $this->configManager->getEntityTypeIdByName($name)) {
@@ -332,6 +353,31 @@ protected function importInvokeOwner($op, $name) {
   }
 
   /**
+   * @param string $name
+   * @return bool
+   */
+  protected function importInvokeRename($name) {
+    $names = explode('::', $name);
+    $old_name = $names[0];
+    $new_name = $names[1];
+    $entity_type_id = $this->configManager->getEntityTypeIdByName($old_name);
+    $old_config = new Config($old_name, $this->storageComparer->getTargetStorage(), $this->eventDispatcher, $this->typedConfigManager);
+    if ($old_data = $this->storageComparer->getTargetStorage()->read($old_name)) {
+      $old_config->initWithData($old_data);
+    }
+
+    $data = $this->storageComparer->getSourceStorage()->read($new_name);
+    $new_config = new Config($new_name, $this->storageComparer->getTargetStorage(), $this->eventDispatcher, $this->typedConfigManager);
+    if ($data !== FALSE) {
+      $new_config->setData($data);
+    }
+
+    $this->configManager->getEntityManager()->getStorageController($entity_type_id)->importRename($new_name, $new_config, $old_name, $old_config);
+    $this->setProcessed('rename', $name);
+    return TRUE;
+  }
+
+  /**
    * Determines if a import is already running.
    *
    * @return bool
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
index 4656897..d10cb18 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
@@ -417,4 +417,19 @@ public function importDelete($name, Config $new_config, Config $old_config) {
     return TRUE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function importRename($new_name, Config $new_config, $old_name, Config $old_config) {
+    $id = static::getIDFromConfigName($old_name, $this->entityType->getConfigPrefix());
+    $entity = $this->load($id);
+    $entity->setSyncing(TRUE);
+    $data = $new_config->get();
+    foreach ($data as $key => $value) {
+      $entity->set($key, $value);
+    }
+    $entity->save();
+    return TRUE;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/StorageComparer.php b/core/lib/Drupal/Core/Config/StorageComparer.php
index ac89537..39b6c52 100644
--- a/core/lib/Drupal/Core/Config/StorageComparer.php
+++ b/core/lib/Drupal/Core/Config/StorageComparer.php
@@ -98,6 +98,7 @@ public function getEmptyChangelist() {
       'create' => array(),
       'update' => array(),
       'delete' => array(),
+      'rename' => array()
     );
   }
 
@@ -133,6 +134,7 @@ public function createChangelist() {
     $this->addChangelistCreate();
     $this->addChangelistUpdate();
     $this->addChangelistDelete();
+    $this->addChangelistRename();
     $this->sourceData = NULL;
     $this->targetData = NULL;
     return $this;
@@ -193,6 +195,30 @@ protected function addChangelistUpdate() {
     }
   }
 
+  public function addChangelistRename() {
+    // Renames will be present in both create and delete lists
+    $create_uuids = array();
+    foreach ($this->getSourceStorage()->readMultiple(array_diff($this->getSourceNames(), $this->getTargetNames())) as $create_id => $data) {
+      if (isset($data['uuid'])) {
+        $create_uuids[$data['uuid']] = $create_id;
+      }
+    }
+    $renames = array();
+    foreach ($this->getTargetStorage()->readMultiple(array_diff($this->getTargetNames(), $this->getSourceNames())) as $delete_id => $data) {
+      if (isset($data['uuid']) && isset($create_uuids[$data['uuid']])) {
+        $renames[] = $delete_id . '::' . $create_uuids[$data['uuid']];
+
+        $key = array_search($create_uuids[$data['uuid']], $this->changelist['create']);
+        unset($this->changelist['create'][$key]);
+        $key = array_search($delete_id, $this->changelist['delete']);
+        unset($this->changelist['delete'][$key]);
+      }
+    }
+    // Reverse the array until we can manage dependencies.
+    $this->addChangeList('rename', array_reverse($renames));
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -205,7 +231,7 @@ public function reset() {
   /**
    * {@inheritdoc}
    */
-  public function hasChanges($ops = array('delete', 'create', 'update')) {
+  public function hasChanges($ops = array('delete', 'create', 'update', 'rename')) {
     foreach ($ops as $op) {
       if (!empty($this->changelist[$op])) {
         return TRUE;
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImportRenameTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImportRenameTest.php
new file mode 100644
index 0000000..f862cce
--- /dev/null
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImportRenameTest.php
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config\Tests\ConfigImportRenameTest.
+ */
+
+namespace Drupal\config\Tests;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Config\ConfigImporter;
+use Drupal\Core\Config\StorageComparer;
+use Drupal\simpletest\DrupalUnitTestBase;
+
+/**
+ * Tests importing renamed configuration from files into active configuration.
+ */
+class ConfigImportRenameTest extends DrupalUnitTestBase {
+
+  /**
+   * Config Importer object used for testing.
+   *
+   * @var \Drupal\Core\Config\ConfigImporter
+   */
+  protected $configImporter;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('system', 'node', 'field', 'text', 'entity');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Import renamed configuration',
+      'description' => 'Tests importing renamed configuration.',
+      'group' => 'Configuration',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->installSchema('system', 'config_snapshot');
+    $this->installSchema('node', 'node');
+
+    // Set up the ConfigImporter object for testing.
+    $storage_comparer = new StorageComparer(
+      $this->container->get('config.storage.staging'),
+      $this->container->get('config.storage')
+    );
+    $this->configImporter = new ConfigImporter(
+      $storage_comparer->createChangelist(),
+      $this->container->get('event_dispatcher'),
+      $this->container->get('config.manager'),
+      $this->container->get('lock'),
+      $this->container->get('config.typed')
+    );
+    $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging'));
+  }
+
+  public function testRenamed() {
+    $content_type = entity_create('node_type', array(
+      'type' => Unicode::strtolower($this->randomName(16)),
+      'name' => $this->randomName(),
+    ));
+    $content_type->save();
+    /** @var \Drupal\Core\Config\StorageInterface $active */
+    $active = $this->container->get('config.storage');
+    /** @var \Drupal\Core\Config\StorageInterface $staging */
+    $staging = $this->container->get('config.storage.staging');
+
+    $config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
+    $this->copyConfig($active, $staging);
+
+    // Change the machine name of the content type. This wil rename 5 configuration
+    // entities: the node type, the body field, the body field instance, the
+    // entity form display and the entity view display.
+    $content_type->type = Unicode::strtolower($this->randomName(8));
+    $content_type->save();
+    $renamed_config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
+    $this->assertTrue($active->exists($renamed_config_name), 'Content type has new name in active store.');
+    $this->assertFalse($active->exists($config_name), 'Content type\'s old name does not exist active store.');
+
+    $this->configImporter->reset();
+    $this->assertEqual(0, count($this->configImporter->getUnprocessed('create')), 'There are no configuration items to create.');
+    $this->assertEqual(0, count($this->configImporter->getUnprocessed('delete')), 'There are no configuration items to delete.');
+    $this->assertEqual(0, count($this->configImporter->getUnprocessed('update')), 'There are no configuration items to update.');
+    $this->assertEqual(5, count($this->configImporter->getUnprocessed('rename')), 'There are 5 configuration items to rename.');
+
+    // If we try to do this then we fail badly because of secondary writes and
+    // deletes.
+    //$this->configImporter->import();
+  }
+
+  public function testSameName() {
+    $type_name = Unicode::strtolower($this->randomName(16));
+    $content_type = entity_create('node_type', array(
+      'type' => $type_name,
+      'name' => 'first node type',
+    ));
+    $content_type->save();
+    /** @var \Drupal\Core\Config\StorageInterface $active */
+    $active = $this->container->get('config.storage');
+    /** @var \Drupal\Core\Config\StorageInterface $staging */
+    $staging = $this->container->get('config.storage.staging');
+
+    $config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
+    $this->copyConfig($active, $staging);
+
+    // Change the machine name of the content type. This wil rename 5 configuration
+    // entities: the node type, the body field, the body field instance, the
+    // entity form display and the entity view displays for teaser and default.
+    $content_type->delete();
+    $this->assertFalse($active->exists($config_name), 'Content type\'s old name does not exist active store.');
+    // Recreate with the same type - this will have a different UUID.
+    $content_type = entity_create('node_type', array(
+      'type' => $type_name,
+      'name' => 'second node type',
+    ));
+    $content_type->save();
+
+    $this->configImporter->reset();
+    $this->assertEqual(6, count($this->configImporter->getUnprocessed('create')), 'There are 6 configuration items to create.');
+    $this->assertEqual(6, count($this->configImporter->getUnprocessed('delete')), 'There are 6 configuration items to delete.');
+    $this->assertEqual(0, count($this->configImporter->getUnprocessed('update')), 'There are no configuration items to update.');
+    $this->assertEqual(0, count($this->configImporter->getUnprocessed('rename')), 'There are no configuration items to rename.');
+
+    $this->configImporter->import();
+
+    // Verify that there is nothing more to import.
+    $this->assertFalse($this->configImporter->reset()->hasUnprocessedChanges());
+    $content_type = entity_load('node_type', $type_name);
+    $this->assertEqual('first node type', $content_type->label());
+  }
+
+
+}
+
