diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index 12a4543..45e3fe8 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Plugin\ConfigurablePluginInterface;
 use Drupal\Component\Utility\String;
 use Drupal\Core\Cache\Cache;
+use Drupal\Core\Config\ConfigException;
 use Drupal\Core\Config\Schema\SchemaIncompleteException;
 use Drupal\Core\Entity\Entity;
 use Drupal\Core\Config\ConfigDuplicateUUIDException;
@@ -430,6 +431,7 @@ public function getConfigTarget() {
    * {@inheritdoc}
    */
   public function onDependencyRemoval(array $dependencies) {
+    return FALSE;
   }
 
   /**
@@ -452,4 +454,33 @@ protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_typ
     Cache::invalidateTags($entity_type->getListCacheTags());
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function preDelete(EntityStorageInterface $storage, array $entities) {
+    foreach ($entities as $entity) {
+      if ($entity->isUninstalling() || $entity->isSyncing()) {
+        // During extension uninstall and configuration synchronization
+        // deletions are already managed.
+        break;
+      }
+
+      // Fix or remove any dependencies.
+      while ($dependents = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities('config', [$entity->getConfigDependencyName()])) {
+        $dependent = reset($dependents);
+        $dependencies_for_removal = [
+          'config' => [$entity],
+          'content' => [],
+          'module' => [],
+          'theme' => []
+        ];
+        if (!$dependent->onDependencyRemoval($dependencies_for_removal)) {
+          $dependent->delete();
+        }
+      }
+    }
+
+    parent::preDelete($storage, $entities);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
index 15347e3..5b813e1 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
@@ -162,15 +162,15 @@ public function calculateDependencies();
    * widgets and formatters if the plugin that supplies them depends on a
    * module that is being uninstalled.
    *
-   * @todo https://www.drupal.org/node/2336727 this method is only fired during
-   *   extension uninstallation but it could be used during config entity
-   *   deletion too.
-   *
    * @param array $dependencies
    *   An array of dependencies that will be deleted keyed by dependency type.
    *   Dependency types are, for example, entity, module and theme.
    *
+   * @return bool
+   *   TRUE if the entity has been changed as a result, FALSE if not.
+   *
    * @see \Drupal\Core\Config\Entity\ConfigDependencyManager
+   * @see \Drupal\Core\Config\ConfigEntityBase::preDelete()
    * @see \Drupal\Core\Config\ConfigManager::uninstall()
    * @see \Drupal\Core\Entity\EntityDisplayBase::onDependencyRemoval()
    */
diff --git a/core/lib/Drupal/Core/Entity/EntityDeleteForm.php b/core/lib/Drupal/Core/Entity/EntityDeleteForm.php
index 71560a2..93c1c13 100644
--- a/core/lib/Drupal/Core/Entity/EntityDeleteForm.php
+++ b/core/lib/Drupal/Core/Entity/EntityDeleteForm.php
@@ -6,6 +6,8 @@
  */
 
 namespace Drupal\Core\Entity;
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Form\FormStateInterface;
 
 /**
  * Provides a generic base class for an entity deletion form.
@@ -16,4 +18,60 @@ class EntityDeleteForm extends EntityConfirmFormBase {
 
   use EntityDeleteFormTrait;
 
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildForm($form, $form_state);
+    $entity = $this->getEntity();
+    // Only do dependency processing for configuration entities. Whilst it is
+    // possible for a configuration entity to be dependent on a content entity,
+    // these dependencies are soft and content delete permissions are often
+    // given to more users. The in this method should not make assumptions that
+    // $entity is a configuration entity in case we decide to change this later.
+    if (!($entity instanceof ConfigEntityInterface)) {
+      return $form;
+    }
+    $dependent_entities = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities($entity->getConfigDependencyKey(), [$entity->getConfigDependencyName()]);
+
+    $form['other_entities'] = array(
+      '#type' => 'details',
+      '#title' => $this->t('Affected configuration'),
+      '#description' => $this->t('The listed configuration will be updated if possible, or deleted.'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#access' => FALSE,
+    );
+    foreach ($dependent_entities as $dependent_entity) {
+      $entity_type_id = $dependent_entity->getEntityTypeId();
+      if (!isset($form['entities'][$entity_type_id])) {
+        $entity_type = $this->entityManager->getDefinition($entity_type_id);
+        // Store the ID and label to sort the dependent_entity types and
+        // entities later.
+        $label = $entity_type->getLabel();
+        $entity_types[$entity_type_id] = $label;
+        $form['other_entities'][$entity_type_id] = array(
+          '#theme' => 'item_list',
+          '#title' => $label,
+          '#items' => array(),
+        );
+      }
+      $form['other_entities'][$entity_type_id]['#items'][] = $dependent_entity->label() ?: $dependent_entity->id();
+    }
+    if (!empty($dependent_entities)) {
+      $form['other_entities']['#access'] = TRUE;
+
+      // Add a weight key to the dependent entity type sections.
+      asort($entity_types, SORT_FLAG_CASE);
+      $weight = 0;
+      foreach ($entity_types as $entity_type_id => $label) {
+        $form['other_entities'][$entity_type_id]['#weight'] = $weight;
+        // Sort the list of dependent_entity labels alphabetically.
+        sort($form['other_entities'][$entity_type_id]['#items'], SORT_FLAG_CASE);
+        $weight++;
+      }
+    }
+
+    return $form;
+  }
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
index 05c0144..0b9eaa3 100644
--- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
@@ -440,6 +440,7 @@ public function onDependencyRemoval(array $dependencies) {
     if ($changed) {
       $this->save();
     }
+    return $changed;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Field/FieldConfigBase.php b/core/lib/Drupal/Core/Field/FieldConfigBase.php
index af1c399..0b791fc 100644
--- a/core/lib/Drupal/Core/Field/FieldConfigBase.php
+++ b/core/lib/Drupal/Core/Field/FieldConfigBase.php
@@ -267,6 +267,20 @@ public function calculateDependencies() {
   /**
    * {@inheritdoc}
    */
+  public function onDependencyRemoval(array $dependencies) {
+    $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
+    $definition = $field_type_manager->getDefinition($this->getType());
+    $changed = $definition['class']::onDependencyRemoval($this, $dependencies);
+    if ($changed) {
+      $this->save();
+    }
+    return $changed;
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
   public function postCreate(EntityStorageInterface $storage) {
     parent::postCreate($storage);
     // If it was not present in the $values passed to create(), (e.g. for
diff --git a/core/lib/Drupal/Core/Field/FieldItemBase.php b/core/lib/Drupal/Core/Field/FieldItemBase.php
index b411b88..b2119e3 100644
--- a/core/lib/Drupal/Core/Field/FieldItemBase.php
+++ b/core/lib/Drupal/Core/Field/FieldItemBase.php
@@ -273,4 +273,11 @@ public static function calculateDependencies(FieldDefinitionInterface $field_def
     return array();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function onDependencyRemoval(FieldDefinitionInterface $field_definition, array $dependencies) {
+    return FALSE;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php
index 1d0de29..f74b3f7 100644
--- a/core/lib/Drupal/Core/Field/FieldItemInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php
@@ -405,4 +405,20 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state);
    */
   public static function calculateDependencies(FieldDefinitionInterface $field_definition);
 
+  /**
+   * Informs the plugin that a dependency of the field will be deleted.
+   *
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The field definition.
+   * @param array $dependencies
+   *   An array of dependencies that will be deleted keyed by dependency type.
+   *   Dependency types are, for example, entity, module and theme.
+   *
+   * @return bool
+   *   TRUE if the field definition has been changed as a result, FALSE if not.
+   *
+   * @see \Drupal\Core\Config\ConfigEntityInterface::onDependencyRemoval()
+   */
+  public static function onDependencyRemoval(FieldDefinitionInterface $field_definition, array $dependencies);
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index e03750d..10497ad 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -286,4 +286,26 @@ public static function calculateDependencies(FieldDefinitionInterface $field_def
     return $dependencies;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function onDependencyRemoval(FieldDefinitionInterface $field_definition, array $dependencies) {
+    $changed = FALSE;
+    if (is_array($field_definition->default_value) && count($field_definition->default_value)) {
+      $target_entity_type = \Drupal::entityManager()->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type'));
+      foreach ($field_definition->default_value as $default_value) {
+        if (is_array($default_value) && isset($default_value['target_uuid'])) {
+          $entity = \Drupal::entityManager()->loadEntityByUuid($target_entity_type->id(), $default_value['target_uuid']);
+          // If the entity does not exist do not create the dependency.
+          // @see \Drupal\Core\Field\EntityReferenceFieldItemList::processDefaultValue()
+          if ($entity && in_array($entity, $dependencies[$target_entity_type->getConfigDependencyKey()])) {
+            $field_definition->default_value = [];
+            $changed = TRUE;
+          }
+        }
+      }
+    }
+    return $changed;
+  }
+
 }
diff --git a/core/modules/config/src/Tests/ConfigImporterTest.php b/core/modules/config/src/Tests/ConfigImporterTest.php
index d2c7cf0..bfef3a8 100644
--- a/core/modules/config/src/Tests/ConfigImporterTest.php
+++ b/core/modules/config/src/Tests/ConfigImporterTest.php
@@ -381,6 +381,10 @@ function testSecondaryUpdateDeletedDeleterFirst() {
 
   /**
    * Tests that secondary updates for deleted files work as expected.
+   *
+   * This test is completely hypothetical since we only support full
+   * configuration tree imports. Therefore, any configuration updates that cause
+   * secondary deletes should be reflected already in the staged configuration.
    */
   function testSecondaryUpdateDeletedDeleteeFirst() {
     $name_deleter = 'config_test.dynamic.deleter';
@@ -416,10 +420,10 @@ function testSecondaryUpdateDeletedDeleteeFirst() {
     $this->configImporter->reset()->import();
 
     $entity_storage = \Drupal::entityManager()->getStorage('config_test');
-    $deleter = $entity_storage->load('deleter');
-    $this->assertEqual($deleter->id(), 'deleter');
-    $this->assertEqual($deleter->uuid(), $values_deleter['uuid']);
-    $this->assertEqual($deleter->label(), $values_deleter['label']);
+    // Both entities are deleted. ConfigTest::postSave() causes updates of the
+    // deleter entity to delete the deletee entity. Since the deleter depends on
+    // the deletee, removing the deletee causes the deleter to be removed.
+    $this->assertFalse($entity_storage->load('deleter'));
     // @todo The deletee entity does not exist as the update worked but the
     //   entity was deleted after that. There is also no log message as this
     //   happened outside of the config importer.
diff --git a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php
index 4357597..ff024a5 100644
--- a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php
+++ b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php
@@ -136,6 +136,7 @@ public function onDependencyRemoval(array $dependencies) {
     if ($changed) {
       $this->save();
     }
+    return $changed;
   }
 
   /**
diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceIntegrationTest.php b/core/modules/entity_reference/src/Tests/EntityReferenceIntegrationTest.php
index 6c5f8fc..90cc352 100644
--- a/core/modules/entity_reference/src/Tests/EntityReferenceIntegrationTest.php
+++ b/core/modules/entity_reference/src/Tests/EntityReferenceIntegrationTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Utility\String;
 use Drupal\config\Tests\AssertConfigEntityImportTrait;
+use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
 
@@ -152,6 +153,9 @@ public function testSupportedEntityTypesAndWidgets() {
       // Ensure that the field can be imported without change even after the
       // default value deleted.
       $referenced_entities[0]->delete();
+      // Reload the field since deleting the default value can change the field.
+      \Drupal::entityManager()->getStorage($field->getEntityTypeId())->resetCache([$field->id()]);
+      $field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
       $this->assertConfigEntityImport($field);
 
       // Once the default value has been removed after saving the dependency
diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php
index dc5607a..d91d286 100644
--- a/core/modules/field/src/Entity/FieldConfig.php
+++ b/core/modules/field/src/Entity/FieldConfig.php
@@ -182,6 +182,7 @@ public function calculateDependencies() {
   public static function preDelete(EntityStorageInterface $storage, array $fields) {
     $state = \Drupal::state();
 
+    parent::preDelete($storage, $fields);
     // Keep the field definitions in the state storage so we can use them
     // later during field_purge_batch().
     $deleted_fields = $state->get('field.field.deleted') ?: array();
@@ -222,7 +223,7 @@ public static function postDelete(EntityStorageInterface $storage, array $fields
     $storages_to_delete = array();
     foreach ($fields as $field) {
       $storage_definition = $field->getFieldStorageDefinition();
-      if (!$field->deleted && empty($field->noFieldDelete) && !$field->isUninstalling() && $storage_definition->isDeletable()) {
+      if (!$field->deleted && !$field->isUninstalling() && $storage_definition->isDeletable()) {
         // Key by field UUID to avoid deleting the same storage twice.
         $storages_to_delete[$storage_definition->uuid()] = $storage_definition;
       }
@@ -230,29 +231,6 @@ public static function postDelete(EntityStorageInterface $storage, array $fields
     if ($storages_to_delete) {
       \Drupal::entityManager()->getStorage('field_storage_config')->delete($storages_to_delete);
     }
-
-    // Cleanup entity displays.
-    $displays_to_update = array();
-    foreach ($fields as $field) {
-      if (!$field->deleted) {
-        $view_modes = \Drupal::entityManager()->getViewModeOptions($field->entity_type, TRUE);
-        foreach (array_keys($view_modes) as $mode) {
-          $displays_to_update['entity_view_display'][$field->entity_type . '.' . $field->bundle . '.' . $mode][] = $field->getName();
-        }
-        $form_modes = \Drupal::entityManager()->getFormModeOptions($field->entity_type, TRUE);
-        foreach (array_keys($form_modes) as $mode) {
-          $displays_to_update['entity_form_display'][$field->entity_type . '.' . $field->bundle . '.' . $mode][] = $field->getName();
-        }
-      }
-    }
-    foreach ($displays_to_update as $type => $ids) {
-      foreach (entity_load_multiple($type, array_keys($ids)) as $id => $display) {
-        foreach ($ids[$id] as $field_name) {
-          $display->removeComponent($field_name);
-        }
-        $display->save();
-      }
-    }
   }
 
   /**
diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php
index 829aeef..02fbd0f 100644
--- a/core/modules/field/src/Entity/FieldStorageConfig.php
+++ b/core/modules/field/src/Entity/FieldStorageConfig.php
@@ -198,6 +198,13 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI
   protected $propertyDefinitions;
 
   /**
+   * Static flag set to prevent recursion during field deletes.
+   *
+   * @var bool
+   */
+  protected static $inDeletion = FALSE;
+
+  /**
    * Constructs a FieldStorageConfig object.
    *
    * @param array $values
@@ -374,27 +381,13 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
    */
   public static function preDelete(EntityStorageInterface $storage, array $field_storages) {
     $state = \Drupal::state();
-    $field_config_storage = \Drupal::entityManager()->getStorage('field_config');
 
-    // Delete fields first. Note: when deleting a field storage through
-    // FieldConfig::postDelete(), the fields have been deleted already, so
-    // no fields will be found here.
-    $field_ids = array();
-    foreach ($field_storages as $field_storage) {
-      if (!$field_storage->deleted) {
-        foreach ($field_storage->getBundles() as $bundle) {
-          $field_ids[] = "{$field_storage->entity_type}.$bundle.{$field_storage->field_name}";
-        }
-      }
-    }
-    if ($field_ids) {
-      $fields = $field_config_storage->loadMultiple($field_ids);
-      // Tag the objects to preserve recursive deletion of the field.
-      foreach ($fields as $field) {
-        $field->noFieldDelete = TRUE;
-      }
-      $field_config_storage->delete($fields);
-    }
+    // Set the static flag so that we don't delete field storages whilst
+    // deleting fields.
+    self::$inDeletion = TRUE;
+
+    // Delete or fix any configuration that is dependent, for example, fields.
+    parent::preDelete($storage, $field_storages);
 
     // Keep the field definitions in the state storage so we can use them later
     // during field_purge_batch().
@@ -422,6 +415,8 @@ public static function postDelete(EntityStorageInterface $storage, array $fields
         $field->deleted = TRUE;
       }
     }
+    // Unset static flag.
+    self::$inDeletion = FALSE;
   }
 
   /**
@@ -744,8 +739,9 @@ public static function loadByName($entity_type_id, $field_name) {
    */
   public function isDeletable() {
     // The field storage is not deleted, is configured to be removed when there
-    // are no fields and the field storage has no bundles.
-    return !$this->deleted && !$this->persist_with_no_fields && count($this->getBundles()) == 0;
+    // are no fields, the field storage has no bundles, and field storages are
+    // not in the process of being deleted.
+    return !$this->deleted && !$this->persist_with_no_fields && count($this->getBundles()) == 0 && !self::$inDeletion;
   }
 
 }
diff --git a/core/modules/filter/src/Entity/FilterFormat.php b/core/modules/filter/src/Entity/FilterFormat.php
index dc4643a..036c730 100644
--- a/core/modules/filter/src/Entity/FilterFormat.php
+++ b/core/modules/filter/src/Entity/FilterFormat.php
@@ -413,6 +413,7 @@ public function onDependencyRemoval(array $dependencies) {
     if ($changed) {
       $this->save();
     }
+    return $changed;
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
index 4ed1c20..9ef8466 100644
--- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
@@ -97,6 +97,13 @@ class ConfigEntityStorageTest extends UnitTestCase {
   protected $typedConfigManager;
 
   /**
+   * The configuration manager.
+   *
+   * @var \Drupal\Core\Config\ConfigManagerInterface
+   */
+  protected $configManager;
+
+  /**
    * {@inheritdoc}
    *
    * @covers ::__construct
@@ -160,10 +167,14 @@ protected function setUp() {
     $this->typedConfigManager->expects($this->any())
       ->method('getDefinition')
       ->will($this->returnValue(array('mapping' => array('id' => '', 'uuid' => '', 'dependencies' => ''))));
+
+    $this->configManager = $this->getMock('Drupal\Core\Config\ConfigManagerInterface');
+
     $container = new ContainerBuilder();
     $container->set('entity.manager', $this->entityManager);
     $container->set('config.typed', $this->typedConfigManager);
     $container->set('cache_tags.invalidator', $this->cacheTagsInvalidator);
+    $container->set('config.manager', $this->configManager);
     \Drupal::setContainer($container);
 
   }
