diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 9d31839..1a951e1 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -205,8 +205,9 @@ function block_rebuild() {
  */
 function block_theme_suggestions_block(array $variables) {
   $suggestions = array();
+  $provider = $variables['elements']['#configuration']['provider'];
 
-  $suggestions[] = 'block__' . $variables['elements']['#configuration']['provider'];
+  $suggestions[] = 'block__' . $provider;
   // Hyphens (-) and underscores (_) play a special role in theme suggestions.
   // Theme suggestions should only contain underscores, because within
   // drupal_find_theme_templates(), underscores are converted to hyphens to
@@ -216,16 +217,33 @@ function block_theme_suggestions_block(array $variables) {
   // and your function names won't be recognized. So, we need to convert
   // hyphens to underscores in block deltas for the theme suggestions.
 
-  // We can safely explode on : because we know the Block plugin type manager
-  // enforces that delimiter for all derivatives.
-  $parts = explode(':', $variables['elements']['#plugin_id']);
-  $suggestion = 'block';
-  while ($part = array_shift($parts)) {
-    $suggestions[] = $suggestion .= '__' . strtr($part, '-', '_');
+  if ($provider == 'block_content') {
+    $entity = $variables['elements']['content']['#block_content'];
+    $bundle_name = $entity->bundle();
+    $entity_id = $entity->id();
+    $block_id = $variables['elements']['#id'];
+    $sanitized_view_mode = strtr($variables['elements']['#configuration']['block_content']['view_mode'], '.', '_');
+
+    $suggestions[] = 'block__block_content' . '__' . $sanitized_view_mode;
+    $suggestions[] = 'block__block_content' . '__' . $bundle_name;
+    $suggestions[] = 'block__block_content' . '__' . $bundle_name . '__' . $sanitized_view_mode;
+    $suggestions[] = 'block__block_content' . '__' . $entity_id;
+    $suggestions[] = 'block__block_content' . '__' . $block_id;
+    $suggestions[] = 'block__block_content' . '__' . $entity_id . '__' . $sanitized_view_mode;
+    $suggestions[] = 'block__block_content' . '__' . $block_id . '__' . $sanitized_view_mode;
   }
+  else {
+    // We can safely explode on : because we know the Block plugin type manager
+    // enforces that delimiter for all derivatives.
+    $parts = explode(':', $variables['elements']['#plugin_id']);
+    $suggestion = 'block';
+    while ($part = array_shift($parts)) {
+      $suggestions[] = $suggestion .= '__' . strtr($part, '-', '_');
+    }
 
-  if (!empty($variables['elements']['#id'])) {
-    $suggestions[] = 'block__' . $variables['elements']['#id'];
+    if (!empty($variables['elements']['#id'])) {
+      $suggestions[] = 'block__' . $variables['elements']['#id'];
+    }
   }
 
   return $suggestions;
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index e252d7e..01068e3 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -552,23 +552,6 @@ function node_preprocess_block(&$variables) {
 }
 
 /**
- * Implements hook_theme_suggestions_HOOK().
- */
-function node_theme_suggestions_node(array $variables) {
-  $suggestions = array();
-  $node = $variables['elements']['#node'];
-  $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
-
-  $suggestions[] = 'node__' . $sanitized_view_mode;
-  $suggestions[] = 'node__' . $node->bundle();
-  $suggestions[] = 'node__' . $node->bundle() . '__' . $sanitized_view_mode;
-  $suggestions[] = 'node__' . $node->id();
-  $suggestions[] = 'node__' . $node->id() . '__' . $sanitized_view_mode;
-
-  return $suggestions;
-}
-
-/**
  * Prepares variables for node templates.
  *
  * Default template: node.html.twig.
diff --git a/core/modules/node/src/Tests/NodeTemplateSuggestionsTest.php b/core/modules/node/src/Tests/NodeTemplateSuggestionsTest.php
index fef6aa0..9af0624 100644
--- a/core/modules/node/src/Tests/NodeTemplateSuggestionsTest.php
+++ b/core/modules/node/src/Tests/NodeTemplateSuggestionsTest.php
@@ -26,16 +26,19 @@ function testNodeThemeHookSuggestions() {
     $build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode);
 
     $variables['elements'] = $build;
-    $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', array($variables));
+    $suggestions = array();
+    $hook = 'node';
+    \Drupal::moduleHandler()->alter('theme_suggestions', $suggestions, $variables, $hook);
 
     $this->assertEqual($suggestions, array('node__full', 'node__page', 'node__page__full', 'node__' . $node->id(), 'node__' . $node->id() . '__full'), 'Found expected node suggestions.');
 
     // Change the view mode.
     $view_mode = 'node.my_custom_view_mode';
     $build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode);
-
     $variables['elements'] = $build;
-    $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', array($variables));
+
+    $suggestions = array();
+    \Drupal::moduleHandler()->alter('theme_suggestions', $suggestions, $variables, $hook);
 
     $this->assertEqual($suggestions, array('node__node_my_custom_view_mode', 'node__page', 'node__page__node_my_custom_view_mode', 'node__' . $node->id(), 'node__' . $node->id() . '__node_my_custom_view_mode'), 'Found expected node suggestions.');
   }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 6ca3699..7f857be 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -302,6 +302,29 @@ function system_theme_suggestions_field(array $variables) {
   return $suggestions;
 }
 
+
+/**
+ * Implements hook_theme_suggestions_alter().
+ */
+function system_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
+  if (isset($variables['elements']['#view_mode'])) {
+    $entity_definition = \Drupal::entityManager()->getDefinition($hook, FALSE);
+    if ($entity_definition && $entity_definition->hasViewBuilderClass()) {
+      $entity = $variables['elements']["#$hook"];
+      $entity_type_id = $entity->getEntityTypeId();
+      $bundle_name = $entity->bundle();
+      $entity_id = $entity->id();
+      $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
+
+      $suggestions[] = $entity_type_id . '__' . $sanitized_view_mode;
+      $suggestions[] = $entity_type_id . '__' . $bundle_name;
+      $suggestions[] = $entity_type_id . '__' . $bundle_name . '__' . $sanitized_view_mode;
+      $suggestions[] = $entity_type_id . '__' . $entity_id;
+      $suggestions[] = $entity_type_id . '__' . $entity_id . '__' . $sanitized_view_mode;
+    }
+  }
+}
+
 /**
  * Implements hook_stream_wrappers().
  */
