diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 65349a3..25a91a1 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2040,6 +2040,12 @@ function template_preprocess(&$variables, $hook, $info) {
       $variables['attributes'] = NestedArray::mergeDeep($variables['attributes'], $variables[$key]['#attributes']);
     }
   }
+
+  // If this is an entity being rendered, call the preprocess() method on the
+  // view builder.
+  if (isset($variables['elements']['#entity_type']) && isset($variables['elements']['#view_mode'])) {
+    \Drupal::entityManager()->getViewBuilder($variables['elements']['#entity_type'])->preprocess($variables);
+  }
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index d886224..02a39be 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -133,6 +133,7 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco
       "#{$this->entityType}" => $entity,
       '#view_mode' => $view_mode,
       '#langcode' => $langcode,
+      '#entity_type' => $this->entityType,
     );
 
     // Cache the rendered output if permitted by the view mode and global entity
@@ -265,4 +266,19 @@ public function resetCache(array $entities = NULL) {
       \Drupal::cache($this->cacheBin)->deleteTags(array($this->entityType . '_view' => TRUE));
     }
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preprocess(array &$variables) {
+    $variables['view_mode'] = $variables['elements']['#view_mode'];
+    $variables[$this->entityType] = $variables['elements']['#' . $this->entityType];
+
+    // Helpful $content variable for templates.
+    $variables += array('content' => array());
+    foreach (element_children($variables['elements']) as $key) {
+      $variables['content'][$key] = $variables['elements'][$key];
+    }
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
index 0d026f2..285a068 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
@@ -84,4 +84,12 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
    */
   public function resetCache(array $entities = NULL);
 
+  /**
+   * Preprocess variables.
+   *
+   * @param array $variables
+   *   An associative array containing the entity variables to be rendered.
+   */
+  public function preprocess(array &$variables);
+
 }
diff --git a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
index 5aed185..52dba76 100644
--- a/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
+++ b/core/modules/block/lib/Drupal/block/BlockViewBuilder.php
@@ -70,4 +70,10 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
    */
   public function resetCache(array $ids = NULL) { }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function preprocess(array &$variables) {
+  }
+
 }
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index df12f82..fdb077a 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1374,9 +1374,8 @@ function comment_prepare_author(CommentInterface $comment) {
  *     Array keys: #comment, #commented_entity.
  */
 function template_preprocess_comment(&$variables) {
-  $comment = $variables['elements']['#comment'];
+  $comment = $variables['comment'];
   $commented_entity = entity_load($comment->entity_type->value, $comment->entity_id->value);
-  $variables['comment'] = $comment;
   $variables['commented_entity'] = $commented_entity;
 
   $account = comment_prepare_author($comment);
@@ -1456,11 +1455,6 @@ function template_preprocess_comment(&$variables) {
     $variables['parent'] = '';
   }
 
-  // Helpful $content variable for templates.
-  foreach (element_children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
-
   // Set status to a string representation of comment->status.
   if (isset($comment->in_preview)) {
     $variables['status'] = 'preview';
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 8becc7f..130ffc0 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -662,10 +662,8 @@ function node_theme_suggestions_node(array $variables) {
  *   - view_mode: View mode; e.g., 'full', 'teaser'...
  */
 function template_preprocess_node(&$variables) {
-  $variables['view_mode'] = $variables['elements']['#view_mode'];
   // Provide a distinct $teaser boolean.
   $variables['teaser'] = $variables['view_mode'] == 'teaser';
-  $variables['node'] = $variables['elements']['#node'];
   $node = $variables['node'];
 
   $variables['date'] = format_date($node->getCreatedTime());
@@ -682,12 +680,6 @@ function template_preprocess_node(&$variables) {
   unset($variables['elements']['title']);
   $variables['page'] = $variables['view_mode'] == 'full' && node_is_page($node);
 
-  // Helpful $content variable for templates.
-  $variables += array('content' => array());
-  foreach (element_children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
-
   // Display post information only on certain node types.
   // Avoid loading the entire node type config entity here that may not exist.
   $node_type_config = \Drupal::config('node.type.' . $node->bundle());
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index e41b467..334bdfe 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -384,8 +384,6 @@ function taxonomy_theme_suggestions_taxonomy_term(array $variables) {
  *   - attributes: HTML attributes for the containing element.
  */
 function template_preprocess_taxonomy_term(&$variables) {
-  $variables['view_mode'] = $variables['elements']['#view_mode'];
-  $variables['term'] = $variables['elements']['#term'];
   $term = $variables['term'];
 
   $uri = $term->uri();
@@ -394,12 +392,6 @@ function template_preprocess_taxonomy_term(&$variables) {
   $variables['name'] = check_plain($term->label());
   $variables['page'] = $variables['view_mode'] == 'full' && taxonomy_term_is_page($term);
 
-  // Helpful $content variable for templates.
-  $variables['content'] = array();
-  foreach (element_children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
-
   // Gather classes, and clean up name so there are no underscores.
   $variables['attributes']['class'][] = 'taxonomy-term';
   $vocabulary_name_css = str_replace('_', '-', $term->bundle());
diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc
index f9b5a91..2f5ca22 100644
--- a/core/modules/user/user.pages.inc
+++ b/core/modules/user/user.pages.inc
@@ -106,13 +106,6 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
  *   - account: The user account.
  */
 function template_preprocess_user(&$variables) {
-  $account = $variables['elements']['#user'];
-
-  // Helpful $content variable for templates.
-  foreach (element_children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
-
   // Set up attributes.
   $variables['attributes']['class'][] = 'profile';
 }
