diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index adb402b..18b978f 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -43,6 +43,13 @@
 class EntityManager extends PluginManagerBase implements EntityManagerInterface {
 
   /**
+   * Extra fields by bundle.
+   *
+   * @var array
+   */
+  protected $extraFields = array();
+
+  /**
    * The injection container that should be passed into the controller factory.
    *
    * @var \Symfony\Component\DependencyInjection\ContainerInterface
@@ -163,6 +170,7 @@ public function clearCachedDefinitions() {
 
     $this->bundleInfo = NULL;
     $this->displayModeInfo = array();
+    $this->extraFields = array();
   }
 
   /**
@@ -520,6 +528,42 @@ public function getAllBundleInfo() {
   /**
    * {@inheritdoc}
    */
+  public function getExtraFields($entity_type_id, $bundle) {
+    // Read from the "static" cache.
+    if (isset($this->extraFields[$entity_type_id][$bundle])) {
+      return $this->extraFields[$entity_type_id][$bundle];
+    }
+
+    // Read from the persistent cache. Since hook_entity_extra_field_info() and
+    // hook_entity_extra_field_info_alter() might contain t() calls, we cache
+    // per language.
+    $cache_id = 'entity_bundle_extra_fields:' . $entity_type_id . ':' . $bundle . ':' . $this->languageManager->getCurrentLanguage()->id;
+    $cached = $this->cache->get($cache_id);
+    if ($cached) {
+      $this->extraFields[$entity_type_id][$bundle] = $cached->data;
+      return $this->extraFields[$entity_type_id][$bundle];
+    }
+
+    $extra = $this->moduleHandler->invokeAll('entity_extra_field_info');
+    $this->moduleHandler->alter('entity_extra_field_info', $extra);
+    $info = isset($extra[$entity_type_id][$bundle]) ? $extra[$entity_type_id][$bundle] : array();
+    $info += array(
+      'form' => array(),
+      'display' => array(),
+    );
+
+    // Store in the 'static' and persistent caches.
+    $this->extraFields[$entity_type_id][$bundle] = $info;
+    $this->cache->set($cache_id, $info, Cache::PERMANENT, array(
+      'entity_field_info' => TRUE,
+    ));
+
+    return $this->extraFields[$entity_type_id][$bundle];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getEntityTypeLabels() {
     $options = array();
     foreach ($this->getDefinitions() as $entity_type => $definition) {
diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
index 424af7d..ce964ab 100644
--- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
@@ -187,6 +187,35 @@ public function getController($entity_type, $controller_type);
   public function getBundleInfo($entity_type);
 
   /**
+   * Retrieves the "extra fields" for a bundle.
+   *
+   * @param string $entity_type_id
+   *   The entity type ID.
+   * @param string $bundle
+   *   The bundle name.
+   *
+   * @return array
+   *   A nested array of 'pseudo-field' elements. Each list is nested within the
+   *   following keys: entity type, bundle name, context (either 'form' or
+   *   'display'). The keys are the name of the elements as appearing in the
+   *   renderable array (either the entity form or the displayed entity). The
+   *   value is an associative array:
+   *   - label: The human readable name of the element. Make sure you sanitize
+   *     this appropriately.
+   *   - description: A short description of the element contents.
+   *   - weight: The default weight of the element.
+   *   - visible: (optional) The default visibility of the element. Defaults to
+   *     TRUE.
+   *   - edit: (optional) String containing markup (normally a link) used as the
+   *     element's 'edit' operation in the administration interface. Only for
+   *     'form' context.
+   *   - delete: (optional) String containing markup (normally a link) used as the
+   *     element's 'delete' operation in the administration interface. Only for
+   *     'form' context.
+   */
+  public function getExtraFields($entity_type_id, $bundle);
+
+  /**
    * Returns the entity translation to be used in the given context.
    *
    * This will check whether a translation for the desired language is available
diff --git a/core/modules/comment/comment.api.php b/core/modules/comment/comment.api.php
index 00b8efc..8507f13 100644
--- a/core/modules/comment/comment.api.php
+++ b/core/modules/comment/comment.api.php
@@ -99,7 +99,7 @@ function hook_comment_load(Drupal\comment\Comment $comments) {
 function hook_comment_view(\Drupal\comment\Entity\Comment $comment, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode, $langcode) {
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
-  // node type in hook_field_extra_fields().
+  // node type in hook_entity_extra_field_info().
   if ($display->getComponent('mymodule_addition')) {
     $comment->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($comment),
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 103c5c8..55622b5 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -121,9 +121,9 @@ function comment_uri(CommentInterface $comment) {
 }
 
 /**
- * Implements hook_field_extra_fields().
+ * Implements hook_entity_extra_field_info().
  */
-function comment_field_extra_fields() {
+function comment_entity_extra_field_info() {
   $return = array();
   foreach (\Drupal::service('comment.manager')->getAllFields() as $entity_type => $fields) {
     foreach ($fields as $field_name => $field_info) {
diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module
index 3894e8f..84bd1cd 100644
--- a/core/modules/contact/contact.module
+++ b/core/modules/contact/contact.module
@@ -92,9 +92,9 @@ function contact_entity_bundle_info() {
 }
 
 /**
- * Implements hook_field_extra_fields().
+ * Implements hook_entity_extra_field_info().
  */
-function contact_field_extra_fields() {
+function contact_entity_extra_field_info() {
   $fields = array();
   foreach (array_keys(entity_get_bundles('contact_message')) as $bundle) {
     $fields['contact_message'][$bundle]['form']['name'] = array(
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 68c0a7e..8f1b6b7 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -662,9 +662,9 @@ function content_translation_entity_update(EntityInterface $entity) {
 }
 
 /**
- * Implements hook_field_extra_fields().
+ * Implements hook_entity_extra_field_info().
  */
-function content_translation_field_extra_fields() {
+function content_translation_entity_extra_field_info() {
   $extra = array();
 
   foreach (\Drupal::entityManager()->getDefinitions() as $entity_type => $info) {
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 24141bd..e62c50a 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -9,97 +9,6 @@
 use Drupal\field\FieldConfigUpdateForbiddenException;
 
 /**
- * Exposes "pseudo-field" components on fieldable entities.
- *
- * Field UI's "Manage display" and "Manage form display" pages let users
- * re-order fields rendered through the regular widget/formatter pipeline, but
- * also other components: entity fields that are rendered through custom code,
- * or other arbitrary components added through hook_form_alter() or
- * hook_entity_view().
- *
- * Fieldable entities or modules that want to have their components supported
- * should expose them using this hook. The user-defined settings (weight,
- * visible) are automatically applied on rendered forms and displayed entities
- * by ContentEntityFormController::form() and EntityViewBuilder::viewMultiple().
- *
- * @see hook_field_extra_fields_alter()
- *
- * @return array
- *   A nested array of 'pseudo-field' elements. Each list is nested within the
- *   following keys: entity type, bundle name, context (either 'form' or
- *   'display'). The keys are the name of the elements as appearing in the
- *   renderable array (either the entity form or the displayed entity). The
- *   value is an associative array:
- *   - label: The human readable name of the element. Make sure you sanitize
- *     this appropriately.
- *   - description: A short description of the element contents.
- *   - weight: The default weight of the element.
- *   - visible: (optional) The default visibility of the element. Defaults to
- *     TRUE.
- *   - edit: (optional) String containing markup (normally a link) used as the
- *     element's 'edit' operation in the administration interface. Only for
- *     'form' context.
- *   - delete: (optional) String containing markup (normally a link) used as the
- *     element's 'delete' operation in the administration interface. Only for
- *     'form' context.
- */
-function hook_field_extra_fields() {
-  $extra = array();
-  $module_language_enabled = \Drupal::moduleHandler()->moduleExists('language');
-  $description = t('Node module element');
-
-  foreach (node_type_get_types() as $bundle) {
-    if ($bundle->has_title) {
-      $extra['node'][$bundle->type]['form']['title'] = array(
-        'label' => check_plain($bundle->title_label),
-        'description' => $description,
-        'weight' => -5,
-      );
-    }
-
-    // Add also the 'language' select if Language module is enabled and the
-    // bundle has multilingual support.
-    // Visibility of the ordering of the language selector is the same as on the
-    // node/add form.
-    if ($module_language_enabled) {
-      $configuration = language_get_default_configuration('node', $bundle->type);
-      if ($configuration['language_show']) {
-        $extra['node'][$bundle->type]['form']['language'] = array(
-          'label' => t('Language'),
-          'description' => $description,
-          'weight' => 0,
-        );
-      }
-    }
-    $extra['node'][$bundle->type]['display']['language'] = array(
-      'label' => t('Language'),
-      'description' => $description,
-      'weight' => 0,
-      'visible' => FALSE,
-    );
-  }
-
-  return $extra;
-}
-
-/**
- * Alter "pseudo-field" components on fieldable entities.
- *
- * @param $info
- *   The associative array of 'pseudo-field' components.
- *
- * @see hook_field_extra_fields()
- */
-function hook_field_extra_fields_alter(&$info) {
-  // Force node title to always be at the top of the list by default.
-  foreach (node_type_get_types() as $bundle) {
-    if (isset($info['node'][$bundle->type]['form']['title'])) {
-      $info['node'][$bundle->type]['form']['title']['weight'] = -20;
-    }
-  }
-}
-
-/**
  * @defgroup field_types Field Types API
  * @{
  * Defines field, widget, display formatter, and storage types.
diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc
index 119f6fa..8aba57b 100644
--- a/core/modules/field/field.info.inc
+++ b/core/modules/field/field.info.inc
@@ -117,9 +117,12 @@ function field_info_fields() {
  *
  * @return
  *   The array of pseudo-field elements in the bundle.
+ *
+ * @deprecated in Drupal 8.x-dev. Use
+ *   \Drupal::entityManager()->getExtraFields() instead.
  */
 function field_info_extra_fields($entity_type, $bundle, $context) {
-  $info = Field::fieldInfo()->getBundleExtraFields($entity_type, $bundle);
+  $info = \Drupal::entityManager()->getExtraFields($entity_type, $bundle);
 
   return isset($info[$context]) ? $info[$context] : array();
 }
diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php
index 969b719..808a31b 100644
--- a/core/modules/field/lib/Drupal/field/FieldInfo.php
+++ b/core/modules/field/lib/Drupal/field/FieldInfo.php
@@ -125,13 +125,6 @@ class FieldInfo {
   protected $emptyBundles = array();
 
   /**
-   * Extra fields by bundle.
-   *
-   * @var array
-   */
-  protected $bundleExtraFields = array();
-
-  /**
    * Constructs this FieldInfo object.
    *
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
@@ -168,8 +161,6 @@ public function flush() {
     $this->loadedAllInstances = FALSE;
     $this->emptyBundles = array();
 
-    $this->bundleExtraFields = array();
-
     Cache::deleteTags(array('field_info' => TRUE));
   }
 
@@ -522,47 +513,6 @@ function getInstance($entity_type, $bundle, $field_name) {
   }
 
   /**
-   * Retrieves the "extra fields" for a bundle.
-   *
-   * @param string $entity_type
-   *   The entity type.
-   * @param string $bundle
-   *   The bundle name.
-   *
-   * @return array
-   *   The array of extra fields.
-   */
-  public function getBundleExtraFields($entity_type, $bundle) {
-    // Read from the "static" cache.
-    if (isset($this->bundleExtraFields[$entity_type][$bundle])) {
-      return $this->bundleExtraFields[$entity_type][$bundle];
-    }
-
-    // Read from the persistent cache. Since hook_field_extra_fields() and
-    // hook_field_extra_fields_alter() might contain t() calls, we cache per
-    // language.
-    $langcode = $this->languageManager->getCurrentLanguage()->id;
-    if ($cached = $this->cacheBackend->get("field_info:bundle_extra:$langcode:$entity_type:$bundle")) {
-      $this->bundleExtraFields[$entity_type][$bundle] = $cached->data;
-      return $this->bundleExtraFields[$entity_type][$bundle];
-    }
-
-    // Cache miss: read from hook_field_extra_fields(). Note: given the current
-    // shape of the hook, we have no other way than collecting extra fields on
-    // all bundles.
-    $extra = $this->moduleHandler->invokeAll('field_extra_fields');
-    $this->moduleHandler->alter('field_extra_fields', $extra);
-    $info = isset($extra[$entity_type][$bundle]) ? $extra[$entity_type][$bundle] : array();
-    $info += array('form' => array(), 'display' => array());
-
-    // Store in the 'static' and persistent caches.
-    $this->bundleExtraFields[$entity_type][$bundle] = $info;
-    $this->cacheBackend->set("field_info:bundle_extra:$langcode:$entity_type:$bundle", $info, Cache::PERMANENT, array('field_info' => TRUE));
-
-    return $this->bundleExtraFields[$entity_type][$bundle];
-  }
-
-  /**
    * Prepares a field for the current run-time context.
    *
    * @param \Drupal\field\FieldConfigInterface $field
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
index 3f2e116..4999a83 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
@@ -363,39 +363,4 @@ protected function getExpectedFieldTypeDefinition() {
     );
   }
 
-  /**
-   * Tests that the extra fields can be translated.
-   */
-  function testFieldInfoExtraFieldsTranslation() {
-    $this->enableModules(array('language', 'locale'));
-    $this->installSchema('locale', array('locales_source', 'locales_target', 'locales_location'));
-    foreach (array('en', 'hu') as $id) {
-      $language = new Language(array(
-        'id' => $id,
-      ));
-      language_save($language);
-    }
-    $locale_storage = $this->container->get('locale.storage');
-
-    // Create test source string.
-    $en_string = $locale_storage->createString(array(
-      'source' => 'User name and password',
-      'context' => '',
-    ))->save();
-
-    // Create translation for new string and save it.
-    $translated_string = $this->randomString();
-    $locale_storage->createTranslation(array(
-      'lid' => $en_string->lid,
-      'language' => 'hu',
-      'translation' => $translated_string,
-    ))->save();
-
-    // Check that the label is translated.
-    \Drupal::translation()->setDefaultLangcode('hu');
-    $field_info = \Drupal::service('field.info');
-    $user_fields = $field_info->getBundleExtraFields('user', 'user');
-    $this->assertEqual($user_fields['form']['account']['label'], $translated_string);
-  }
-
 }
diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module
index 5ece040..45a0c0d 100644
--- a/core/modules/field/tests/modules/field_test/field_test.module
+++ b/core/modules/field/tests/modules/field_test/field_test.module
@@ -194,9 +194,9 @@ function field_test_field_formatter_settings_summary_alter(&$summary, $context)
 }
 
 /**
- * Implements hook_field_extra_fields_alter().
+ * Implements hook_entity_extra_field_info_alter().
  */
-function field_test_field_extra_fields_alter(&$info) {
+function field_test_entity_extra_field_info_alter(&$info) {
   // Remove all extra fields from the 'no_fields' content type;
   unset($info['node']['no_fields']);
 }
diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php
index 1616fad..4ea7212 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -797,7 +797,7 @@ function hook_node_submit(\Drupal\node\NodeInterface $node, $form, &$form_state)
 function hook_node_view(\Drupal\node\NodeInterface $node, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode, $langcode) {
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
-  // node type in hook_field_extra_fields().
+  // node type in hook_entity_extra_field_info().
   if ($display->getComponent('mymodule_addition')) {
     $node->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($node),
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index cc53539..d847788 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -445,9 +445,9 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') {
 }
 
 /**
- * Implements hook_field_extra_fields().
+ * Implements hook_entity_extra_field_info().
  */
-function node_field_extra_fields() {
+function node_entity_extra_field_info() {
   $extra = array();
   $module_language_enabled = \Drupal::moduleHandler()->moduleExists('language');
   $description = t('Node module element');
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index c960371..203b9ce 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -5,6 +5,7 @@
  * Hooks provided the Entity module.
  */
 
+use Drupal\Component\Utility\String;
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Field\FieldDefinition;
 
@@ -456,7 +457,7 @@ function hook_entity_query_alter(\Drupal\Core\Entity\Query\QueryInterface $query
 function hook_entity_view(\Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode, $langcode) {
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
-  // entity bundle in hook_field_extra_fields().
+  // entity bundle in hook_entity_extra_field_info().
   if ($display->getComponent('mymodule_addition')) {
     $entity->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($entity),
@@ -524,7 +525,7 @@ function hook_entity_prepare_view($entity_type_id, array $entities, array $displ
   if (!empty($entities) && $entity_type_id == 'user') {
     // Only do the extra work if the component is configured to be
     // displayed. This assumes a 'mymodule_addition' extra field has been
-    // defined for the entity bundle in hook_field_extra_fields().
+    // defined for the entity bundle in hook_entity_extra_field_info().
     $ids = array();
     foreach ($entities as $id => $entity) {
       if ($displays[$entity->bundle()]->getComponent('mymodule_addition')) {
@@ -819,6 +820,7 @@ function hook_entity_field_access($operation, \Drupal\Core\Field\FieldDefinition
  *     (\Drupal\Core\Field\FieldItemListInterface).
  */
 function hook_entity_field_access_alter(array &$grants, array $context) {
+  /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
   $field_definition = $context['field_definition'];
   if ($field_definition->getName() == 'field_of_interest' && $grants['node'] === FALSE) {
     // Override node module's restriction to no opinion. We don't want to
@@ -829,3 +831,78 @@ function hook_entity_field_access_alter(array &$grants, array $context) {
     $grants['node'] = NULL;
   }
 }
+
+/**
+ * Exposes "pseudo-field" components on content entities.
+ *
+ * Field UI's "Manage fields" and "Manage display" pages let users re-order
+ * fields, but also non-field components. For nodes, these include elements
+ * exposed by modules through hook_form_alter(), for instance.
+ *
+ * Content entities or modules that want to have their components supported
+ * should expose them using this hook. The user-defined settings (weight,
+ * visible) are automatically applied when entities or entity forms are
+ * rendered.
+ *
+ * @see hook_entity_extra_field_info_alter()
+ *
+ * @return array
+ *   The array structure is identical to that of the return value of
+ *   \Drupal\Core\Entity\EntityManagerInterface::getExtraFields().
+ */
+function hook_entity_extra_field_info() {
+  $extra = array();
+  $module_language_enabled = \Drupal::moduleHandler()->moduleExists('language');
+  $description = t('Node module element');
+
+  foreach (node_type_get_types() as $bundle) {
+    if ($bundle->has_title) {
+      $extra['node'][$bundle->type]['form']['title'] = array(
+        'label' => String::checkPlain($bundle->title_label),
+        'description' => $description,
+        'weight' => -5,
+      );
+    }
+
+    // Add also the 'language' select if Language module is enabled and the
+    // bundle has multilingual support.
+    // Visibility of the ordering of the language selector is the same as on the
+    // node/add form.
+    if ($module_language_enabled) {
+      $configuration = language_get_default_configuration('node', $bundle->type);
+      if ($configuration['language_show']) {
+        $extra['node'][$bundle->type]['form']['language'] = array(
+          'label' => t('Language'),
+          'description' => $description,
+          'weight' => 0,
+        );
+      }
+    }
+    $extra['node'][$bundle->type]['display']['language'] = array(
+      'label' => t('Language'),
+      'description' => $description,
+      'weight' => 0,
+      'visible' => FALSE,
+    );
+  }
+
+  return $extra;
+}
+
+/**
+ * Alter "pseudo-field" components on content entities.
+ *
+ * @param array $info
+ *   The array structure is identical to that of the return value of
+ *   \Drupal\Core\Entity\EntityManagerInterface::getExtraFields().
+ *
+ * @see hook_entity_extra_field_info()
+ */
+function hook_entity_extra_field_info_alter(&$info) {
+  // Force node title to always be at the top of the list by default.
+  foreach (node_type_get_types() as $bundle) {
+    if (isset($info['node'][$bundle->type]['form']['title'])) {
+      $info['node'][$bundle->type]['form']['title']['weight'] = -20;
+    }
+  }
+}
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index d7a08fc..9bc9682 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -196,9 +196,9 @@ function entity_test_entity_form_mode_info_alter(&$form_modes) {
 }
 
 /**
- * Implements hook_field_extra_fields().
+ * Implements hook_entity_extra_field_info().
  */
-function entity_test_field_extra_fields() {
+function entity_test_entity_extra_field_info() {
   $extra['entity_test']['bundle_with_extra_fields'] = array(
     'display' => array(
       // Note: those extra fields do not currently display anything, they are
diff --git a/core/modules/taxonomy/taxonomy.api.php b/core/modules/taxonomy/taxonomy.api.php
index 1c32203..960cff2 100644
--- a/core/modules/taxonomy/taxonomy.api.php
+++ b/core/modules/taxonomy/taxonomy.api.php
@@ -262,7 +262,7 @@ function hook_taxonomy_term_delete(Drupal\taxonomy\Term $term) {
 function hook_taxonomy_term_view(\Drupal\taxonomy\Entity\Term $term, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode, $langcode) {
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
-  // vocabulary in hook_field_extra_fields().
+  // vocabulary in hook_entity_extra_field_info().
   if ($display->getComponent('mymodule_addition')) {
     $term->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($term),
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index d5a307e..b7046b4 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -135,9 +135,9 @@ function taxonomy_term_uri($term) {
 }
 
 /**
- * Implements hook_field_extra_fields().
+ * Implements hook_entity_extra_field_info().
  */
-function taxonomy_field_extra_fields() {
+function taxonomy_entity_extra_field_info() {
   $return = array();
   foreach (entity_get_bundles('taxonomy_term') as $bundle => $bundle_info) {
     $return['taxonomy_term'][$bundle] = array(
diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php
index 7e7c3f8..b71a65f 100644
--- a/core/modules/user/user.api.php
+++ b/core/modules/user/user.api.php
@@ -324,7 +324,7 @@ function hook_user_logout($account) {
 function hook_user_view(\Drupal\user\UserInterface $account, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode, $langcode) {
   // Only do the extra work if the component is configured to be displayed.
   // This assumes a 'mymodule_addition' extra field has been defined for the
-  // user entity type in hook_field_extra_fields().
+  // user entity type in hook_entity_extra_field_info().
   if ($display->getComponent('mymodule_addition')) {
     $account->content['mymodule_addition'] = array(
       '#markup' => mymodule_addition($account),
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index edecd89..22d24c2 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -205,9 +205,9 @@ function user_picture_enabled() {
 }
 
 /**
- * Implements hook_field_extra_fields().
+ * Implements hook_entity_extra_field_info().
  */
-function user_field_extra_fields() {
+function user_entity_extra_field_info() {
   $fields['user']['user']['form']['account'] = array(
     'label' => t('User name and password'),
     'description' => t('User module account form elements.'),
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
index 4f60ac1..b16008c 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
@@ -817,6 +817,58 @@ public function testGetTranslationFromContext() {
   }
 
   /**
+   * @covers ::getExtraFields
+   */
+  function testgetExtraFields() {
+    $this->setUpEntityManager();
+
+    $entity_type_id = $this->randomName();
+    $bundle = $this->randomName();
+    $language_code = 'en';
+    $hook_bundle_extra_fields = array(
+      $entity_type_id => array(
+        $bundle => array(
+          'form' => array(
+            'foo_extra_field' => array(
+              'label' => 'Foo',
+            ),
+          ),
+        ),
+      ),
+    );
+    $processed_hook_bundle_extra_fields = $hook_bundle_extra_fields;
+    $processed_hook_bundle_extra_fields[$entity_type_id][$bundle] += array(
+      'display' => array(),
+    );
+    $cache_id = 'entity_bundle_extra_fields:' . $entity_type_id . ':' . $bundle . ':' . $language_code;
+
+    $language = new Language();
+    $language->id = $language_code;
+
+    $this->languageManager->expects($this->once())
+      ->method('getCurrentLanguage')
+      ->will($this->returnValue($language));
+
+    $this->cache->expects($this->once())
+      ->method('get')
+      ->with($cache_id);
+
+    $this->moduleHandler->expects($this->once())
+      ->method('invokeAll')
+      ->with('entity_extra_field_info')
+      ->will($this->returnValue($hook_bundle_extra_fields));
+    $this->moduleHandler->expects($this->once())
+      ->method('alter')
+      ->with('entity_extra_field_info', $hook_bundle_extra_fields);
+
+    $this->cache->expects($this->once())
+      ->method('set')
+      ->with($cache_id, $processed_hook_bundle_extra_fields[$entity_type_id][$bundle]);
+
+    $this->assertSame($processed_hook_bundle_extra_fields[$entity_type_id][$bundle], $this->entityManager->getExtraFields($entity_type_id, $bundle));
+  }
+
+  /**
    * Gets a mock controller class name.
    *
    * @return string
