diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php
index 22cf527..d3bca5f 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php
@@ -11,7 +11,6 @@
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Language\Language;
-use Drupal\field\FieldInfo;
 use Drupal\field\FieldConfigUpdateForbiddenException;
 use Drupal\field\FieldConfigInterface;
 use Drupal\field\FieldInstanceConfigInterface;
@@ -73,11 +72,11 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase {
   protected $database;
 
   /**
-   * The field info object.
+   * The entity manager.
    *
-   * @var \Drupal\field\FieldInfo
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $fieldInfo;
+  protected $entityManager;
 
   /**
    * {@inheritdoc}
@@ -86,7 +85,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
     return new static(
       $entity_type,
       $container->get('database'),
-      $container->get('field.info')
+      $container->get('entity.manager')
     );
   }
 
@@ -97,14 +96,14 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
    *   The entity type definition.
    * @param \Drupal\Core\Database\Connection $database
    *   The database connection to be used.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
    */
-  public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info) {
+  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager) {
     parent::__construct($entity_type);
 
     $this->database = $database;
-    $this->fieldInfo = $field_info;
+    $this->entityManager = $entity_manager;
 
     // Check if the entity type supports IDs.
     if ($this->entityType->hasKey('id')) {
@@ -791,8 +790,10 @@ protected function doLoadFieldItems($entities, $age) {
     // Collect impacted fields.
     $fields = array();
     foreach ($bundles as $bundle => $v) {
-      foreach ($this->fieldInfo->getBundleInstances($this->entityTypeId, $bundle) as $field_name => $instance) {
-        $fields[$field_name] = $instance->getField();
+      foreach ($this->entityManager->getFieldDefinitions($this->entityTypeId, $bundle) as $field_name => $instance) {
+        if ($instance instanceof FieldInstanceConfigInterface) {
+          $fields[$field_name] = $instance->getField();
+        }
       }
     }
 
@@ -856,7 +857,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
       $vid = $id;
     }
 
-    foreach ($this->fieldInfo->getBundleInstances($entity_type, $bundle) as $field_name => $instance) {
+    foreach ($this->entityManager->getFieldDefinitions($entity_type, $bundle) as $field_name => $instance) {
+      if (!($instance instanceof FieldInstanceConfigInterface)) {
+        continue;
+      }
       $field = $instance->getField();
       $table_name = static::_fieldTableName($field);
       $revision_name = static::_fieldRevisionTableName($field);
@@ -930,7 +934,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
    * {@inheritdoc}
    */
   protected function doDeleteFieldItems(EntityInterface $entity) {
-    foreach ($this->fieldInfo->getBundleInstances($entity->getEntityTypeId(), $entity->bundle()) as $instance) {
+    foreach ($this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $instance) {
+      if (!($instance instanceof FieldInstanceConfigInterface)) {
+        continue;
+      }
       $field = $instance->getField();
       $table_name = static::_fieldTableName($field);
       $revision_name = static::_fieldRevisionTableName($field);
@@ -949,7 +956,10 @@ protected function doDeleteFieldItems(EntityInterface $entity) {
   protected function doDeleteFieldItemsRevision(EntityInterface $entity) {
     $vid = $entity->getRevisionId();
     if (isset($vid)) {
-      foreach ($this->fieldInfo->getBundleInstances($entity->getEntityTypeId(), $entity->bundle()) as $instance) {
+      foreach ($this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $instance) {
+        if (!($instance instanceof FieldInstanceConfigInterface)) {
+          continue;
+        }
         $revision_name = static::_fieldRevisionTableName($instance->getField());
         $this->database->delete($revision_name)
           ->condition('entity_id', $entity->id())
diff --git a/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php
index 180dfef..3b20fe4 100644
--- a/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php
+++ b/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php
@@ -9,16 +9,7 @@
 
 use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Database\Connection;
-use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
-use Drupal\Core\Language\Language;
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Component\Uuid\Uuid;
-use Drupal\field\FieldInfo;
-use Drupal\field\FieldConfigUpdateForbiddenException;
-use Drupal\field\FieldConfigInterface;
-use Drupal\field\FieldInstanceConfigInterface;
-use Drupal\field\Entity\FieldConfig;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -50,13 +41,6 @@ class EntityDatabaseStorage extends EntityStorageBase {
   protected $database;
 
   /**
-   * The field info object.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * {@inheritdoc}
    */
   public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 679f849..234d906 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -135,6 +135,16 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface,
   protected $displayModeInfo = array();
 
   /**
+   * An array keyed by entity type. Each value is an array which keys are
+   * field names and value is an array with two entries:
+   *   - type: The field type.
+   *   - bundles: The bundles in which the field appears.
+   *
+   * @return array
+   */
+  protected $fieldMap = array();
+
+  /**
    * Constructs a new Entity plugin manager.
    *
    * @param \Traversable $namespaces
@@ -514,6 +524,35 @@ public function getFieldStorageDefinitions($entity_type_id) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function getFieldMap() {
+    if (!$this->fieldMap) {
+      // Not prepared, try to load from cache.
+      $cid = 'entity_field_map';
+      if ($cache = $this->cache->get($cid)) {
+        $this->fieldMap = $cache->data;
+      }
+      else {
+        // Rebuild the definitions and put it into the cache.
+        foreach ($this->getDefinitions() as $entity_type_id => $entity_type) {
+          if ($entity_type->isFieldable()) {
+            foreach ($this->getBundleInfo($entity_type_id) as $bundle => $bundle_info) {
+              foreach ($this->getFieldDefinitions($entity_type_id, $bundle) as $field_name => $field_definition) {
+                $this->fieldMap[$entity_type_id][$field_name]['type'] = $field_definition->getType();
+                $this->fieldMap[$entity_type_id][$field_name]['bundles'][] = $bundle;
+              }
+            }
+          }
+        }
+
+        $this->cache->set($cid, $this->fieldMap, Cache::PERMANENT, array('entity_types' => TRUE, 'entity_field_info' => TRUE));
+      }
+    }
+    return $this->fieldMap;
+  }
+
+  /**
    * Builds field storage definitions for an entity type.
    *
    * @param string $entity_type_id
@@ -557,6 +596,7 @@ public function clearCachedFieldDefinitions() {
     $this->baseFieldDefinitions = array();
     $this->fieldDefinitions = array();
     $this->fieldStorageDefinitions = array();
+    $this->fieldMap = array();
     Cache::deleteTags(array('entity_field_info' => TRUE));
   }
 
diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
index da36a36..6ce0ea8 100644
--- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
@@ -77,6 +77,17 @@ public function getFieldDefinitions($entity_type_id, $bundle);
   public function getFieldStorageDefinitions($entity_type_id);
 
   /**
+   * Collects a lightweight map of fields across bundles.
+   *
+   * @return array
+   *   An array keyed by entity type. Each value is an array which keys are
+   *   field names and value is an array with two entries:
+   *   - type: The field type.
+   *   - bundles: The bundles in which the field appears.
+   */
+  public function getFieldMap();
+
+  /**
    * Creates a new access controller instance.
    *
    * @param string $entity_type
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
index ee2bebc..29cb8fa 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
@@ -8,12 +8,12 @@
 namespace Drupal\Core\Entity\Query\Sql;
 
 use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\Core\Entity\ContentEntityTypeInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\ContentEntityDatabaseStorage;
-use Drupal\Core\Entity\Plugin\DataType\EntityReference;
 use Drupal\Core\Entity\Query\QueryException;
 use Drupal\field\Entity\FieldConfig;
-use Drupal\field\Field as FieldInfo;
+use Drupal\field\FieldConfigInterface;
 
 /**
  * Adds tables and fields to the SQL entity query.
@@ -58,7 +58,6 @@ public function __construct(SelectInterface $sql_query) {
   public function addField($field, $type, $langcode) {
     $entity_type_id = $this->sqlQuery->getMetaData('entity_type');
     $entity_manager = \Drupal::entityManager();
-    $field_info = FieldInfo::fieldInfo();
     $age = $this->sqlQuery->getMetaData('age');
     // This variable ensures grouping works correctly. For example:
     // ->condition('tags', 2, '>')
@@ -75,11 +74,12 @@ public function addField($field, $type, $langcode) {
     // system.
     $propertyDefinitions = array();
     $entity_type = $entity_manager->getDefinition($entity_type_id);
-    // Use the lightweight and fast field map for checking whether a specifier
-    // is a field or not. While calling field_info_field() on every specifier
-    // delivers the same information, if no specifiers are using the field API
-    // it is much faster if field_info_field() is never called.
-    $field_map = $field_info->getFieldMap();
+
+    $storage_definitions = array();
+    // @todo Needed for menu links.
+    if ($entity_type instanceof ContentEntityTypeInterface) {
+      $storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id);
+    }
     for ($key = 0; $key <= $count; $key ++) {
       // If there is revision support and only the current revision is being
       // queried then use the revision id. Otherwise, the entity id will do.
@@ -95,25 +95,27 @@ public function addField($field, $type, $langcode) {
         $entity_id_field = $entity_type->getKey('id');
         $field_id_field = 'entity_id';
       }
-      // This can either be the name of an entity property (non-configurable
-      // field), a field API field (a configurable field).
+      // This can either be the name of an entity base field or a configurable
+      // field.
       $specifier = $specifiers[$key];
-      // First, check for field API fields by trying to retrieve the field specified.
       // Normally it is a field name, but field_purge_batch() is passing in
       // id:$field_id so check that first.
+      /* @var \Drupal\Core\Field\FieldDefinitionInterface $field */
       if (substr($specifier, 0, 3) == 'id:') {
-        $field = $field_info->getFieldById((substr($specifier, 3)));
+        if ($fields = entity_load_multiple_by_properties('field_config', array('uuid' => substr($specifier, 3), 'include_deleted' => TRUE))) {
+          $field = current($fields);
+        }
       }
-      elseif (isset($field_map[$entity_type_id][$specifier])) {
-        $field = $field_info->getField($entity_type_id, $specifier);
+      elseif (isset($storage_definitions[$specifier])) {
+        $field = $storage_definitions[$specifier];
       }
       else {
         $field = FALSE;
       }
-      // If we managed to retrieve the field, process it.
-      if ($field) {
+      // If we managed to retrieve a configurable field, process it.
+      if ($field instanceof FieldConfigInterface) {
         // Find the field column.
-        $column = FALSE;
+        $column = $field->getMainPropertyName();
         if ($key < $count) {
           $next = $specifiers[$key + 1];
           // Is this a field column?
@@ -133,39 +135,16 @@ public function addField($field, $type, $langcode) {
           // also use the property definitions for column.
           if ($key < $count) {
             $relationship_specifier = $specifiers[$key + 1];
+            $propertyDefinitions = $field->getPropertyDefinitions();
 
-            // Get the field definitions form a mocked entity.
-            $values = array();
-            $field_name = $field->getName();
-            // If there are bundles, pick one.
-            if ($bundle_key = $entity_type->getKey('bundle')) {
-              $values[$bundle_key] = reset($field_map[$entity_type_id][$field_name]['bundles']);
-            }
-            $entity = $entity_manager
-              ->getStorage($entity_type_id)
-              ->create($values);
-            $propertyDefinitions = $entity->$field_name->getFieldDefinition()->getPropertyDefinitions();
-
-            // If the column is not yet known, ie. the
-            // $node->field_image->entity case then use first property as
-            // column, i.e. target_id or fid.
-            // Otherwise, the code executing the relationship will throw an
-            // exception anyways so no need to do it here.
-            if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field->getName()}->first()->get('entity') instanceof EntityReference) {
-              $column = current(array_keys($propertyDefinitions));
-            }
             // Prepare the next index prefix.
             $next_index_prefix = "$relationship_specifier.$column";
           }
         }
-        else {
-          // If this is the last specifier, default to value.
-          $column = 'value';
-        }
         $table = $this->ensureFieldTable($index_prefix, $field, $type, $langcode, $base_table, $entity_id_field, $field_id_field);
         $sql_column = ContentEntityDatabaseStorage::_fieldColumnName($field, $column);
       }
-      // This is an entity property (non-configurable field).
+      // This is an entity base field (non-configurable field).
       else {
         // ensureEntityTable() decides whether an entity property will be
         // queried from the data table or the base table based on where it
@@ -182,31 +161,20 @@ public function addField($field, $type, $langcode) {
         $table = $this->ensureEntityTable($index_prefix, $specifier, $type, $langcode, $base_table, $entity_id_field, $entity_tables);
       }
       // If there are more specifiers to come, it's a relationship.
-      if ($key < $count) {
+      if ($field && $key < $count) {
         // Computed fields have prepared their property definition already, do
         // it for properties as well.
         if (!$propertyDefinitions) {
-          // Create a relevant entity to find the definition for this
-          // property.
-          $values = array();
-          // If there are bundles, pick one. It does not matter which,
-          // properties exist on all bundles.
-          if ($bundle_key = $entity_type->getKey('bundle')) {
-            $bundles = entity_get_bundles($entity_type_id);
-            $values[$bundle_key] = key($bundles);
-          }
-          $entity = $entity_manager
-            ->getStorage($entity_type_id)
-            ->create($values);
-          $propertyDefinitions = $entity->$specifier->getFieldDefinition()->getPropertyDefinitions();
+          $propertyDefinitions = $field->getPropertyDefinitions();
           $relationship_specifier = $specifiers[$key + 1];
           $next_index_prefix = $relationship_specifier;
         }
         // Check for a valid relationship.
-        if (isset($propertyDefinitions[$relationship_specifier]) && $entity->get($specifier)->first()->get('entity') instanceof EntityReference) {
+        if (isset($propertyDefinitions[$relationship_specifier]) && $field->getPropertyDefinition('entity')->getDataType() == 'entity_reference' ) {
           // If it is, use the entity type.
           $entity_type_id = $propertyDefinitions[$relationship_specifier]->getTargetDefinition()->getEntityTypeId();
           $entity_type = $entity_manager->getDefinition($entity_type_id);
+          $storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id);
           // Add the new entity base table using the table and sql column.
           $join_condition= '%alias.' . $entity_type->getKey('id') . " = $table.$sql_column";
           $base_table = $this->sqlQuery->leftJoin($entity_type->getBaseTable(), NULL, $join_condition);
diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module
index bfe5a39..c84276a 100644
--- a/core/modules/block/custom_block/custom_block.module
+++ b/core/modules/block/custom_block/custom_block.module
@@ -7,6 +7,8 @@
 
 use Drupal\custom_block\Entity\CustomBlockType;
 use Drupal\custom_block\Entity\CustomBlock;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Implements hook_help().
@@ -114,8 +116,8 @@ function custom_block_entity_bundle_info() {
  */
 function custom_block_add_body_field($block_type_id, $label = 'Block body') {
   // Add or remove the body field, as needed.
-  $field = field_info_field('custom_block', 'body');
-  $instance = field_info_instance('custom_block', 'body', $block_type_id);
+  $field = FieldConfig::loadByName('custom_block', 'body');
+  $instance = FieldInstanceConfig::loadByName('custom_block', $block_type_id, 'body');
   if (empty($field)) {
     $field = entity_create('field_config', array(
       'name' => 'body',
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
index 739f234..d193be9 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
@@ -78,8 +78,8 @@ public function testCustomBlockTypeEditing() {
     // We need two block types to prevent /block/add redirecting.
     $this->createCustomBlockType('other');
 
-    $instance = field_info_instance('custom_block', 'body', 'basic');
-    $this->assertEqual($instance->getLabel(), 'Block body', 'Body field was found.');
+    $field_definition = \Drupal::entityManager()->getFieldDefinitions('custom_block', 'other')['body'];
+    $this->assertEqual($field_definition->getLabel(), 'Block body', 'Body field was found.');
 
     // Verify that title and body fields are displayed.
     $this->drupalGet('block/add/basic');
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 539cce8..f6fc45b 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -14,6 +14,7 @@
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Url;
 use Drupal\field\FieldInstanceConfigInterface;
@@ -96,15 +97,18 @@ function comment_help($path, $arg) {
  */
 function comment_entity_bundle_info() {
   $bundles = array();
-  foreach (\Drupal::service('comment.manager')->getAllFields() as $entity_type => $fields) {
-    foreach ($fields as $field_name => $field_info) {
-      $sample_bundle = reset($field_info['bundles']);
-      // We cannot use field info API here because it will result in recursion.
-      $config = \Drupal::config('field.instance.' . $entity_type .  '.' . $sample_bundle . '.' . $field_name);
-      $bundles['comment'][$entity_type . '__' . $field_name] = array(
-        'label' => $config->get('label'),
-      );
-    }
+  $ids = \Drupal::entityQuery('field_config')
+    ->condition('type', 'comment')
+    ->execute();
+  $config_factory = \Drupal::configFactory();
+  foreach ($ids as $id) {
+    list($entity_type_id, $field_name) = explode('.', $id);
+    $instance_ids = $config_factory->listAll('field.instance.' . $id . '.');
+    $instance_id = reset($instance_ids);
+    $config = \Drupal::config('field.instance.' . $instance_id);
+    $bundles['comment'][$entity_type_id . '__' . $field_name] = array(
+      'label' => $config->get('label'),
+    );
   }
   return $bundles;
 }
@@ -1127,16 +1131,15 @@ function comment_num_new($entity_id, $entity_type, $field_name = NULL, $timestam
  *
  * @param int $cid
  *   The comment ID.
- * @param array $instance
- *   Field instance as returned from field_info_instance().
+ * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+ *   Field definition of the comments.
  *
  * @return int
  *   The display ordinal for the comment.
  *
  * @see comment_get_display_page()
- * @see field_info_instance().
  */
-function comment_get_display_ordinal($cid, $instance) {
+function comment_get_display_ordinal($cid, FieldDefinitionInterface $field_definition) {
   // Count how many comments (c1) are before $cid (c2) in display order. This is
   // the 0-based display ordinal.
   $query = db_select('comment', 'c1');
@@ -1147,7 +1150,7 @@ function comment_get_display_ordinal($cid, $instance) {
     $query->condition('c1.status', CommentInterface::PUBLISHED);
   }
 
-  if ($instance->getSetting('default_mode') == COMMENT_MODE_FLAT) {
+  if ($field_definition->getSetting('default_mode') == COMMENT_MODE_FLAT) {
     // For flat comments, cid is used for ordering comments due to
     // unpredictable behavior with timestamp, so we make the same assumption
     // here.
@@ -1171,15 +1174,15 @@ function comment_get_display_ordinal($cid, $instance) {
  *
  * @param int $cid
  *   The comment ID.
- * @param array $instance
- *   Field instance as returned from field_info_instance().
+ * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+ *   Field definition of the comments.
  *
  * @return int
  *   The page number.
  */
-function comment_get_display_page($cid, $instance) {
-  $ordinal = comment_get_display_ordinal($cid, $instance);
-  $comments_per_page = $instance->getSetting('per_page');
+function comment_get_display_page($cid, FieldDefinitionInterface $field_definition) {
+  $ordinal = comment_get_display_ordinal($cid, $field_definition);
+  $comments_per_page = $field_definition->getSetting('per_page');
   return floor($ordinal / $comments_per_page);
 }
 
diff --git a/core/modules/comment/comment.services.yml b/core/modules/comment/comment.services.yml
index 8524045..1f4b77a 100644
--- a/core/modules/comment/comment.services.yml
+++ b/core/modules/comment/comment.services.yml
@@ -7,7 +7,7 @@ services:
 
   comment.manager:
     class: Drupal\comment\CommentManager
-    arguments: ['@field.info', '@entity.manager', '@current_user', '@config.factory', '@string_translation', '@url_generator']
+    arguments: ['@entity.manager', '@current_user', '@config.factory', '@string_translation', '@url_generator']
 
   comment.statistics:
     class: Drupal\comment\CommentStatistics
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
index e9759eb..dfc0691 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
@@ -16,7 +16,6 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
-use Drupal\field\FieldInfo;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -25,13 +24,6 @@
 class CommentFormController extends ContentEntityFormController {
 
   /**
-   * The field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * The current user.
    *
    * @var \Drupal\Core\Session\AccountInterface
@@ -44,7 +36,6 @@ class CommentFormController extends ContentEntityFormController {
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager'),
-      $container->get('field.info'),
       $container->get('current_user')
     );
   }
@@ -59,9 +50,8 @@ public static function create(ContainerInterface $container) {
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   The current user.
    */
-  public function __construct(EntityManagerInterface $entity_manager, FieldInfo $field_info, AccountInterface $current_user) {
+  public function __construct(EntityManagerInterface $entity_manager, AccountInterface $current_user) {
     parent::__construct($entity_manager);
-    $this->fieldInfo = $field_info;
     $this->currentUser = $current_user;
   }
 
@@ -89,13 +79,13 @@ public function form(array $form, array &$form_state) {
     $comment = $this->entity;
     $entity = $this->entityManager->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId());
     $field_name = $comment->getFieldName();
-    $instance = $this->fieldInfo->getInstance($entity->getEntityTypeId(), $entity->bundle(), $field_name);
+    $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()];
 
     // Use #comment-form as unique jump target, regardless of entity type.
     $form['#id'] = drupal_html_id('comment_form');
     $form['#theme'] = array('comment_form__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $field_name, 'comment_form');
 
-    $anonymous_contact = $instance->getSetting('anonymous');
+    $anonymous_contact = $field_definition->getSetting('anonymous');
     $is_admin = $comment->id() && $this->currentUser->hasPermission('administer comments');
 
     if (!$this->currentUser->isAuthenticated() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
@@ -214,7 +204,7 @@ public function form(array $form, array &$form_state) {
       '#title' => $this->t('Subject'),
       '#maxlength' => 64,
       '#default_value' => $comment->getSubject(),
-      '#access' => $instance->getSetting('subject'),
+      '#access' => $field_definition->getSetting('subject'),
     );
 
     // Used for conditional validation of author fields.
@@ -241,8 +231,8 @@ protected function actions(array $form, array &$form_state) {
     /* @var \Drupal\comment\CommentInterface $comment */
     $comment = $this->entity;
     $entity = $comment->getCommentedEntity();
-    $instance = $this->fieldInfo->getInstance($comment->getCommentedEntityTypeId(), $entity->bundle(), $comment->getFieldName());
-    $preview_mode = $instance->getSetting('preview');
+    $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()];
+    $preview_mode = $field_definition->getSetting('preview');
 
     // No delete action on the comment form.
     unset($element['delete']);
@@ -404,8 +394,8 @@ public function save(array $form, array &$form_state) {
       }
       $query = array();
       // Find the current display page for this comment.
-      $instance = $this->fieldInfo->getInstance($entity->getEntityTypeId(), $entity->bundle(), $field_name);
-      $page = comment_get_display_page($comment->id(), $instance);
+      $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$field_name];
+      $page = comment_get_display_page($comment->id(), $field_definition);
       if ($page > 0) {
         $query['page'] = $page;
       }
diff --git a/core/modules/comment/lib/Drupal/comment/CommentManager.php b/core/modules/comment/lib/Drupal/comment/CommentManager.php
index c522fd3..db00db0 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentManager.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentManager.php
@@ -15,7 +15,6 @@
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\TranslationInterface;
-use Drupal\field\FieldInfo;
 
 /**
  * Comment manager contains common functions to manage comment fields.
@@ -23,13 +22,6 @@
 class CommentManager implements CommentManagerInterface {
 
   /**
-   * The field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * The entity manager service.
    *
    * @var \Drupal\Core\Entity\EntityManagerInterface
@@ -74,8 +66,6 @@ class CommentManager implements CommentManagerInterface {
   /**
    * Construct the CommentManager object.
    *
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
    *   The entity manager service.
    * @param \Drupal\Core\Session\AccountInterface $current_user
@@ -87,8 +77,7 @@ class CommentManager implements CommentManagerInterface {
    * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
    *   The url generator service.
    */
-  public function __construct(FieldInfo $field_info, EntityManagerInterface $entity_manager, AccountInterface $current_user, ConfigFactoryInterface $config_factory, TranslationInterface $translation_manager, UrlGeneratorInterface $url_generator) {
-    $this->fieldInfo = $field_info;
+  public function __construct(EntityManagerInterface $entity_manager, AccountInterface $current_user, ConfigFactoryInterface $config_factory, TranslationInterface $translation_manager, UrlGeneratorInterface $url_generator) {
     $this->entityManager = $entity_manager;
     $this->currentUser = $current_user;
     $this->userConfig = $config_factory->get('user.settings');
@@ -123,7 +112,7 @@ public function getFields($entity_type_id) {
    * {@inheritdoc}
    */
   public function getAllFields() {
-    $map = $this->fieldInfo->getFieldMap();
+    $map = $this->entityManager->getFieldMap();
     // Build a list of comment fields only.
     $comment_fields = array();
     foreach ($map as $entity_type => $data) {
@@ -141,7 +130,7 @@ public function getAllFields() {
    */
   public function addDefaultField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN) {
     // Make sure the field doesn't already exist.
-    if (!$this->fieldInfo->getField($entity_type, $field_name)) {
+    if (!$this->entityManager->getStorage('field_config')->load($entity_type . '.' . $field_name)) {
       // Add a default comment field for existing node comments.
       $field = $this->entityManager->getStorage('field_config')->create(array(
         'entity_type' => $entity_type,
@@ -156,7 +145,7 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment',
       $field->save();
     }
     // Make sure the instance doesn't already exist.
-    if (!$this->fieldInfo->getInstance($entity_type, $bundle, $field_name)) {
+    if (!$this->entityManager->getStorage('field_instance_config')->load($entity_type . '.' . $bundle . '.' . $field_name)) {
       $instance = $this->entityManager->getStorage('field_instance_config')->create(array(
         'label' => 'Comment settings',
         'description' => '',
@@ -266,11 +255,10 @@ public function addBodyField($entity_type, $field_name) {
    * {@inheritdoc}
    */
   public function getFieldUIPageTitle($commented_entity_type, $field_name) {
-    $field_info = $this->fieldInfo->getField($commented_entity_type, $field_name);
-    $bundles = $field_info->getBundles();
-    $sample_bundle = reset($bundles);
-    $sample_instance = $this->fieldInfo->getInstance($commented_entity_type, $sample_bundle, $field_name);
-    return String::checkPlain($sample_instance->label);
+    $field_info = $this->getFields($commented_entity_type);
+    $sample_bundle = reset($field_info[$field_name]['bundles']);
+    $sample_definition = $this->entityManager->getFieldDefinitions($commented_entity_type, $sample_bundle)[$field_name];
+    return String::checkPlain($sample_definition->getLabel());
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorage.php b/core/modules/comment/lib/Drupal/comment/CommentStorage.php
index d05b2c3..6343587 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentStorage.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentStorage.php
@@ -9,9 +9,9 @@
 
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\ContentEntityDatabaseStorage;
-use Drupal\field\FieldInfo;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -36,13 +36,13 @@ class CommentStorage extends ContentEntityDatabaseStorage implements CommentStor
    *   An array of entity info for the entity type.
    * @param \Drupal\Core\Database\Connection $database
    *   The database connection to be used.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
    * @param \Drupal\comment\CommentStatisticsInterface $comment_statistics
    *   The comment statistics service.
    */
-  public function __construct(EntityTypeInterface $entity_info, Connection $database, FieldInfo $field_info, CommentStatisticsInterface $comment_statistics) {
-    parent::__construct($entity_info, $database, $field_info);
+  public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, CommentStatisticsInterface $comment_statistics) {
+    parent::__construct($entity_info, $database, $entity_manager);
     $this->statistics = $comment_statistics;
   }
 
@@ -53,7 +53,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
     return new static(
       $entity_info,
       $container->get('database'),
-      $container->get('field.info'),
+      $container->get('entity.manager'),
       $container->get('comment.statistics')
     );
   }
diff --git a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php
index 3661080..ad6f522 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php
@@ -15,7 +15,6 @@
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
 use Drupal\Core\Language\LanguageManagerInterface;
-use Drupal\field\FieldInfo;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -24,13 +23,6 @@
 class CommentViewBuilder extends EntityViewBuilder {
 
   /**
-   * The field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * The module handler service.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface
@@ -52,7 +44,6 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
       $entity_type,
       $container->get('entity.manager'),
       $container->get('language_manager'),
-      $container->get('field.info'),
       $container->get('csrf_token')
     );
   }
@@ -71,9 +62,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
    * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
    *   The CSRF token manager service.
    */
-  public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, FieldInfo $field_info, CsrfTokenGenerator $csrf_token) {
+  public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, CsrfTokenGenerator $csrf_token) {
     parent::__construct($entity_type, $entity_manager, $language_manager);
-    $this->fieldInfo = $field_info;
     $this->csrfToken = $csrf_token;
   }
 
@@ -273,9 +263,9 @@ protected function alterBuild(array &$build, EntityInterface $comment, EntityVie
     if (empty($comment->in_preview)) {
       $prefix = '';
       $commented_entity = $comment->getCommentedEntity();
-      $instance = $this->fieldInfo->getInstance($commented_entity->getEntityTypeId(), $commented_entity->bundle(), $comment->getFieldName());
+      $field_definition = $this->entityManager->getFieldDefinitions($commented_entity->getEntityTypeId(), $commented_entity->bundle())[$comment->getFieldName()];
       $is_threaded = isset($comment->divs)
-        && $instance->getSetting('default_mode') == COMMENT_MODE_THREADED;
+        && $field_definition->getSetting('default_mode') == COMMENT_MODE_THREADED;
 
       // Add indentation div or close open divs as needed.
       if ($is_threaded) {
diff --git a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php
index b0c7cbe..b46a43b 100644
--- a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php
+++ b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php
@@ -8,7 +8,7 @@
 namespace Drupal\comment\Controller;
 
 use Drupal\comment\CommentManagerInterface;
-use Drupal\field\FieldInfo;
+use Drupal\field\FieldConfigInterface;
 use Drupal\Component\Utility\String;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Form\FormBuilderInterface;
@@ -22,13 +22,6 @@
 class AdminController extends ControllerBase {
 
   /**
-   * The field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * The comment manager service.
    *
    * @var \Drupal\comment\CommentManagerInterface
@@ -47,7 +40,6 @@ class AdminController extends ControllerBase {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('field.info'),
       $container->get('comment.manager'),
       $container->get('form_builder')
     );
@@ -56,15 +48,12 @@ public static function create(ContainerInterface $container) {
   /**
    * Constructs an AdminController object.
    *
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
    * @param \Drupal\comment\CommentManagerInterface $comment_manager
    *   The comment manager service.
    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
    *   The form builder.
    */
-  public function __construct(FieldInfo $field_info, CommentManagerInterface $comment_manager, FormBuilderInterface $form_builder) {
-    $this->fieldInfo = $field_info;
+  public function __construct(CommentManagerInterface $comment_manager, FormBuilderInterface $form_builder) {
     $this->commentManager = $comment_manager;
     $this->formBuilder = $form_builder;
   }
@@ -105,24 +94,29 @@ public function overviewBundles() {
     $fields = $this->commentManager->getAllFields();
 
     foreach ($fields as $entity_type => $data) {
+      $storage_definitions = $this->entityManager()->getFieldStorageDefinitions($entity_type);
       foreach ($data as $field_name => $field_info_map) {
-        $field_info = $this->fieldInfo->getField($entity_type, $field_name);
+        $storage_definition = $storage_definitions[$field_name];
         // Initialize the row.
         $row = array(
-          'class' => $field_info->get('locked') ? array('field-disabled') : array(''),
+          'class' => $storage_definition->get('locked') ? array('field-disabled') : array(''),
         );
 
-        $bundles = $field_info->getBundles();
-        $sample_bundle = reset($bundles);
-        $sample_instance = $this->fieldInfo->getInstance($entity_type, $sample_bundle, $field_name);
+        $label = $storage_definition->getLabel();
+        if ($storage_definition instanceof FieldConfigInterface) {
+          $bundles = $storage_definition->getBundles();
+          $sample_bundle = reset($bundles);
+          $field_definitions = $this->entityManager()->getFieldDefinitions($entity_type, $sample_bundle);
+          $label = $field_definitions[$field_name]->getLabel();
+        }
 
         $tokens = array(
-          '@label' => $sample_instance->label,
+          '@label' => $label,
           '@field_name' => $field_name,
         );
-        $row['data']['field_name']['data'] = $field_info->get('locked') ? $this->t('@label (@field_name) (Locked)', $tokens) : $this->t('@label (@field_name)', $tokens);
+        $row['data']['field_name']['data'] = $storage_definition->get('locked') ? $this->t('@label (@field_name) (Locked)', $tokens) : $this->t('@label (@field_name)', $tokens);
 
-        $row['data']['description']['data'] = $field_info->getSetting('description');
+        $row['data']['description']['data'] = $storage_definition->getSetting('description');
         $row['data']['usage']['data'] = array(
           '#theme' => 'item_list',
           '#items' => array(),
@@ -200,7 +194,12 @@ public function bundleInfo($commented_entity_type, $field_name) {
     // Add a link to manage entity fields if the Field UI module is enabled.
     $field_ui_enabled = $this->moduleHandler()->moduleExists('field_ui');
 
-    $field_info = $this->fieldInfo->getField($commented_entity_type, $field_name);
+    $field_storage = $this->entityManager()->getFieldStorageDefinitions($commented_entity_type)[$field_name];
+
+    if (!($field_storage instanceof FieldConfigInterface)) {
+      // @todo: Support base fields.
+      return array();
+    }
 
     $entity_type_info = $this->entityManager()->getDefinition($commented_entity_type);
     $entity_bundle_info = $this->entityManager()->getBundleInfo($commented_entity_type);
@@ -211,7 +210,7 @@ public function bundleInfo($commented_entity_type, $field_name) {
       '#items' => array(),
     );
     // Loop over all of bundles to which this comment field is attached.
-    foreach ($field_info->getBundles() as $bundle) {
+    foreach ($field_storage->getBundles() as $bundle) {
       // Add the current instance to the list of bundles.
       if ($field_ui_enabled && $route_info = FieldUI::getOverviewRouteInfo($commented_entity_type, $bundle)) {
         // Add a link to configure the fields on the given bundle and entity
diff --git a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
index 7829950..78eb686 100644
--- a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
+++ b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
@@ -10,7 +10,6 @@
 use Drupal\comment\CommentInterface;
 use Drupal\comment\CommentManagerInterface;
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
-use Drupal\field\FieldInfo;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Entity\EntityInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -36,13 +35,6 @@ class CommentController extends ControllerBase {
   protected $httpKernel;
 
   /**
-   * Field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * The comment manager service.
    *
    * @var \Drupal\comment\CommentManagerInterface
@@ -54,14 +46,11 @@ class CommentController extends ControllerBase {
    *
    * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
    *   HTTP kernel to handle requests.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   Field Info service.
    * @param \Drupal\comment\CommentManagerInterface $comment_manager
    *   The comment manager service.
    */
-  public function __construct(HttpKernelInterface $http_kernel, FieldInfo $field_info, CommentManagerInterface $comment_manager) {
+  public function __construct(HttpKernelInterface $http_kernel, CommentManagerInterface $comment_manager) {
     $this->httpKernel = $http_kernel;
-    $this->fieldInfo = $field_info;
     $this->commentManager = $comment_manager;
   }
 
@@ -71,7 +60,6 @@ public function __construct(HttpKernelInterface $http_kernel, FieldInfo $field_i
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('http_kernel'),
-      $container->get('field.info'),
       $container->get('comment.manager')
     );
   }
@@ -118,15 +106,15 @@ public function commentApprove(CommentInterface $comment) {
    *   The comment listing set to the page on which the comment appears.
    */
   public function commentPermalink(Request $request, CommentInterface $comment) {
-    if ($entity = $this->entityManager()->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId())) {
+    if ($entity = $comment->getCommentedEntity()) {
       // Check access permissions for the entity.
       if (!$entity->access('view')) {
         throw new AccessDeniedHttpException();
       }
-      $instance = $this->fieldInfo->getInstance($entity->getEntityTypeId(), $entity->bundle(), $comment->getFieldName());
+      $field_definition = $this->entityManager()->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()];
 
       // Find the current display page for this comment.
-      $page = comment_get_display_page($comment->id(), $instance);
+      $page = comment_get_display_page($comment->id(), $field_definition);
       // @todo: Cleaner sub request handling.
       $redirect_request = Request::create($entity->getSystemPath(), 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all());
       $redirect_request->query->set('page', $page);
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
index 24a20a9..86172a1 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\comment\Tests;
 
-use Drupal\field\Field;
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
 
 /**
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
index 139bf73..260834f 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\comment\Tests;
 
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
+use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -74,7 +75,7 @@ function setUp() {
     $this->container->get('comment.manager')->addDefaultField('node', 'article');
 
     // Make comment body translatable.
-    $field = field_info_field('comment', 'comment_body');
+    $field = FieldConfig::loadByName('comment', 'comment_body');
     $field->translatable = TRUE;
     $field->save();
     $this->assertTrue($field->isTranslatable(), 'Comment body is translatable.');
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
index 5e5b4de..119b06d 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
@@ -9,6 +9,7 @@
 
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
 use Drupal\content_translation\Tests\ContentTranslationUITest;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Tests the Comment Translation UI.
@@ -77,7 +78,7 @@ protected function getTranslatorPermissions() {
    */
   function setupTestFields() {
     parent::setupTestFields();
-    $field = field_info_field('comment', 'comment_body');
+    $field = FieldConfig::loadByName('comment', 'comment_body');
     $field->translatable = TRUE;
     $field->save();
   }
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php
index 6127552..5be58c8 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\comment\Tests;
 
+use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -43,14 +44,14 @@ protected function setUp() {
    */
   function testCommentUninstallWithField() {
     // Ensure that the field exists before uninstallation.
-    $field = field_info_field('comment', 'comment_body');
+    $field = FieldConfig::loadByName('comment', 'comment_body');
     $this->assertNotNull($field, 'The comment_body field exists.');
 
     // Uninstall the comment module which should trigger field deletion.
     $this->container->get('module_handler')->uninstall(array('comment'));
 
     // Check that the field is now deleted.
-    $field = field_info_field('comment', 'comment_body');
+    $field = FieldConfig::loadByName('comment', 'comment_body');
     $this->assertNull($field, 'The comment_body field has been deleted.');
   }
 
@@ -60,12 +61,12 @@ function testCommentUninstallWithField() {
    */
   function testCommentUninstallWithoutField() {
     // Manually delete the comment_body field before module uninstallation.
-    $field = field_info_field('comment', 'comment_body');
+    $field = FieldConfig::loadByName('comment', 'comment_body');
     $this->assertNotNull($field, 'The comment_body field exists.');
     $field->delete();
 
     // Check that the field is now deleted.
-    $field = field_info_field('comment', 'comment_body');
+    $field = FieldConfig::loadByName('comment', 'comment_body');
     $this->assertNull($field, 'The comment_body field has been deleted.');
 
     // Ensure that uninstallation succeeds even if the field has already been
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php
index e58947a..ff569d3 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php
@@ -13,7 +13,6 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
-use Drupal\field\Field;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -90,13 +89,12 @@ public function setMapperDefinition($mapper_definition) {
    * {@inheritdoc}
    */
   public function load() {
-    $entities = array();
     // It is not possible to use the standard load method, because this needs
     // all field instance entities only for the given baseEntityType.
-    foreach (Field::fieldInfo()->getInstances($this->baseEntityType) as $fields) {
-      $entities = array_merge($entities, array_values($fields));
-    }
-    return $entities;
+    $ids = \Drupal::entityQuery('field_instance_config')
+      ->condition('entity_type', $this->baseEntityType)
+      ->execute();
+    return $this->storage->loadMultiple($ids);
   }
 
   /**
diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc
index 557f06e..eb03aea 100644
--- a/core/modules/content_translation/content_translation.admin.inc
+++ b/core/modules/content_translation/content_translation.admin.inc
@@ -9,7 +9,7 @@
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Render\Element;
-use Drupal\field\Field as FieldService;
+use Drupal\field\Entity\FieldConfig;
 use Drupal\field\FieldInstanceConfigInterface;
 
 /**
@@ -348,7 +348,7 @@ function _content_translation_update_field_translatability($settings) {
         foreach ($bundle_settings['fields'] as $field_name => $translatable) {
           // If translatability changes for at least one field instance we need
           // to switch field translatability.
-          $field = FieldService::fieldInfo()->getField($entity_type, $field_name);
+          $field = FieldConfig::loadByName($entity_type, $field_name);
           if ($field && $field->isTranslatable() !== $translatable) {
             $fields[$field_name] = $translatable;
           }
@@ -357,7 +357,7 @@ function _content_translation_update_field_translatability($settings) {
     }
     // Store updated fields.
     foreach ($fields as $field_name => $translatable) {
-      $field = FieldService::fieldInfo()->getField($entity_type, $field_name);
+      $field = FieldConfig::loadByName($entity_type, $field_name);
       $field->translatable = $translatable;
       $field->save();
     }
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 38b5b41..ae97a2f 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -14,6 +14,7 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\TypedData\TranslatableInterface;
+use Drupal\field\Entity\FieldInstanceConfig;
 use Drupal\node\NodeInterface;
 
 /**
@@ -865,7 +866,7 @@ function content_translation_save_settings($settings) {
         // Store whether fields have translation enabled or not.
         if (!empty($bundle_settings['columns'])) {
           foreach ($bundle_settings['columns'] as $field_name => $column_settings) {
-            $instance = field_info_instance($entity_type, $field_name, $bundle);
+            $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name);
             if ($instance->isTranslatable()) {
               $instance->settings['translation_sync'] = $column_settings;
             }
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
index a8e1a0c..059cb79 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
@@ -8,7 +8,7 @@
 namespace Drupal\content_translation\Tests;
 
 use Drupal\Core\Language\Language;
-use Drupal\field\Field as FieldService;
+use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -95,7 +95,7 @@ function testSettingsUI() {
     );
     $this->assertSettings('comment', 'node__comment_article', TRUE, $edit);
     field_info_cache_clear();
-    $field = field_info_field('comment', 'comment_body');
+    $field = FieldConfig::loadByName('comment', 'comment_body');
     $this->assertTrue($field->isTranslatable(), 'Comment body is translatable.');
 
     // Test that language settings are correctly stored.
@@ -134,7 +134,7 @@ function testSettingsUI() {
       // Test that configurable field translatability is correctly switched.
       $edit = array('settings[node][article][fields][body]' => $translatable);
       $this->assertSettings('node', 'article', TRUE, $edit);
-      $field = FieldService::fieldInfo()->getField('node', 'body');
+      $field = FieldConfig::loadByName('node', 'body');
       $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article');
       $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.');
       $this->assertEqual($field->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.');
@@ -145,7 +145,7 @@ function testSettingsUI() {
       $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.body/field', $edit, t('Save field settings'));
       field_info_cache_clear();
       entity_info_cache_clear();
-      $field = FieldService::fieldInfo()->getField('node', 'body');
+      $field = FieldConfig::loadByName('node', 'body');
       $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article');
       $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.');
       $this->assertEqual($field->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.');
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
index dd1bfa0..43370fe 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -11,7 +11,7 @@
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Entity\Display\EntityDisplayInterface;
-use Drupal\field\Field;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Provides a common base class for entity view and form displays.
@@ -164,7 +164,7 @@ public function calculateDependencies() {
     // Create dependencies on both hidden and visible fields.
     $fields = $this->content + $this->hidden;
     foreach ($fields as $field_name => $component) {
-      $field_instance = Field::fieldInfo()->getInstance($this->targetEntityType, $this->bundle, $field_name);
+      $field_instance = FieldInstanceConfig::loadByName($this->targetEntityType, $this->bundle, $field_name);
       if ($field_instance) {
         $this->addDependency('entity', $field_instance->getConfigDependencyName());
       }
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 846a723..5d59210 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -10,6 +10,8 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Render\Element;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldInstanceConfig;
 use Drupal\field\FieldConfigInterface;
 
 /**
@@ -91,7 +93,7 @@ function entity_reference_field_config_update(FieldConfigInterface $field) {
 
   foreach ($field->bundles() as $entity_type => $bundles) {
     foreach ($bundles as $bundle) {
-      $instance = field_info_instance($entity_type, $field_name, $bundle);
+      $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name);
       $instance->settings['handler_settings'] = array();
       $instance->save();
     }
@@ -209,8 +211,8 @@ function entity_reference_create_instance($entity_type, $bundle, $field_name, $f
   }
 
   // Look for or add the specified field to the requested entity bundle.
-  $field = field_info_field($entity_type, $field_name);
-  $instance = field_info_instance($entity_type, $field_name, $bundle);
+  $field = FieldConfig::loadByName($entity_type, $field_name);
+  $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name);
 
   if (empty($field)) {
     $field = array(
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php
index f035f37..bde0b2c 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php
@@ -7,8 +7,9 @@
 
 namespace Drupal\entity_reference\Tests;
 
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldInstanceConfig;
 use Drupal\system\Tests\Entity\EntityUnitTestBase;
-use Drupal\field\Field;
 
 /**
  * Tests for the entity reference field.
@@ -88,9 +89,8 @@ public function setUp() {
       array('target_bundles' => array($this->bundle))
     );
 
-    $this->field = Field::fieldInfo()->getField($this->entityType, $this->fieldName);
-    $instances = Field::fieldInfo()->getBundleInstances($this->entityType, $this->bundle);
-    $this->instance = $instances[$this->fieldName];
+    $this->field = FieldConfig::loadByName($this->entityType, $this->fieldName);
+    $this->instance = FieldInstanceConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
   }
 
   /**
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 029db41..5473182 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -8,7 +8,6 @@
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Extension\Extension;
-use Drupal\field\Field;
 
 /*
  * Load all public Field API functions. Drupal currently has no
@@ -200,9 +199,19 @@ function field_entity_field_storage_info(\Drupal\Core\Entity\EntityTypeInterface
  */
 function field_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
   if ($entity_type->isFieldable()) {
-    // Configurable fields, which are always attached to a specific bundle, are
-    // added 'by bundle'.
-    return Field::fieldInfo()->getBundleInstances($entity_type->id(), $bundle);
+    // Query by filtering on the ID as this is more efficient than filtering
+    // on the entity_type property directly.
+    $ids = \Drupal::entityQuery('field_instance_config')
+      ->condition('id', $entity_type->id() . '.' . $bundle . '.', 'STARTS_WITH')
+      ->execute();
+
+    // Fetch all fields and key them by field name.
+    $field_instance_configs = entity_load_multiple('field_instance_config', $ids);
+    $result = array();
+    foreach ($field_instance_configs as $field_instance) {
+      $result[$field_instance->getName()] = $field_instance;
+    }
+    return $result;
   }
 }
 
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
index da29536..7d61db0 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
@@ -770,4 +770,18 @@ protected function getFieldItemClass() {
     return $type_definition['class'];
   }
 
+  /**
+   * Loads a field config entity based on the entity type and field name.
+   *
+   * @param string $entity_type_id
+   *   ID of the entity type.
+   * @param string $field_name
+   *   Name of the field.
+   *
+   * @return static
+   */
+  public static function loadByName($entity_type_id, $field_name) {
+    return \Drupal::entityManager()->getStorage('field_config')->load($entity_type_id . '.' . $field_name);
+  }
+
 }
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php
index ff6217d..b249b68 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php
@@ -12,7 +12,6 @@
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Field\FieldDefinition;
 use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
-use Drupal\field\Field;
 use Drupal\field\FieldException;
 use Drupal\field\FieldInstanceConfigInterface;
 
@@ -232,24 +231,20 @@ class FieldInstanceConfig extends ConfigEntityBase implements FieldInstanceConfi
    * @ingroup field_crud
    */
   public function __construct(array $values, $entity_type = 'field_instance_config') {
-    // Field instances configuration is stored with a 'field_uuid' property
-    // unambiguously identifying the field. We only take it into account if a
-    // 'uuid' entry is present too, so that leftover 'field_uuid' entries
-    // present in config files imported as "default module config" are ignored.
-    if (isset($values['field_uuid']) && isset($values['uuid'])) {
-      $field = Field::fieldInfo()->getFieldById($values['field_uuid']);
+    // Load the corresponding field.
+    if (isset($values['field_name']) && isset($values['entity_type'])) {
+      $field = FieldConfig::loadByName($values['entity_type'], $values['field_name']);
       if (!$field) {
-        throw new FieldException(format_string('Attempt to create an instance of unknown field @uuid', array('@uuid' => $values['field_uuid'])));
-      }
-      $values['field_name'] = $field->getName();
-    }
-    // Alternatively, accept incoming 'field_name' instead of 'field_uuid', for
-    // easier DX on creation of new instances (either through programmatic
-    // creation / or through import of default config files).
-    elseif (isset($values['field_name']) && isset($values['entity_type'])) {
-      $field = Field::fieldInfo()->getField($values['entity_type'], $values['field_name']);
-      if (!$field) {
-        throw new FieldException(format_string('Attempt to create an instance of field @field_name that does not exist on entity type @entity_type.', array('@field_name' => $values['field_name'], '@entity_type' => $values['entity_type'])));
+        // The field might have been deleted, try to load it based on the UUID
+        // when present.
+        if (isset($values['field_uuid']) && isset($values['uuid'])) {
+          if ($fields = entity_load_multiple_by_properties('field_config', array('uuid' => $values['field_uuid'], 'include_deleted' => TRUE))) {
+            $field = current($fields);
+          }
+        }
+        if (!$field) {
+          throw new FieldException(format_string('Attempt to create an instance of field @field_name that does not exist on entity type @entity_type.', array('@field_name' => $values['field_name'], '@entity_type' => $values['entity_type'])));
+        }
       }
       $values['field_uuid'] = $field->uuid();
     }
@@ -808,4 +803,20 @@ public function isDeleted() {
     return $this->deleted;
   }
 
+  /**
+   * Loads a field config entity based on the entity type and field name.
+   *
+   * @param string $entity_type_id
+   *   ID of the entity type.
+   * @param string $bundle
+   *   Bundle name.
+   * @param string $field_name
+   *   Name of the field.
+   *
+   * @return static
+   */
+  public static function loadByName($entity_type_id, $bundle, $field_name) {
+    return \Drupal::entityManager()->getStorage('field_instance_config')->load($entity_type_id . '.' . $bundle . '.' . $field_name);
+  }
+
 }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php b/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php
index 2f0cadb..c948bcb 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php
@@ -34,7 +34,7 @@ class FieldList extends Numeric {
   public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
     parent::init($view, $display, $options);
 
-    $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']);
+    $field = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']];
     $this->allowed_values = options_allowed_values($field);
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php b/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php
index a257cad..14f7a8f 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php
@@ -34,7 +34,7 @@ class ListString extends String {
   public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
     parent::init($view, $display, $options);
 
-    $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']);
+    $field = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']];
     $this->allowed_values = options_allowed_values($field);
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
index 030bd50..b07390d 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
@@ -13,7 +13,6 @@
 use Drupal\Core\Field\FieldDefinition;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Render\Element;
-use Drupal\field\Field as FieldHelper;
 use Drupal\Core\Entity\ContentEntityDatabaseStorage;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FormatterPluginManager;
@@ -146,8 +145,9 @@ public static function create(ContainerInterface $container, array $configuratio
   public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
     parent::init($view, $display, $options);
 
-    $field_storage_definition = FieldHelper::fieldInfo()->getField($this->definition['entity_type'], $this->definition['field_name']);
-    $this->field_info = FieldDefinition::createFromFieldStorageDefinition($field_storage_definition);
+
+    $storage_definition = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']];
+    $this->field_info = FieldDefinition::createFromFieldStorageDefinition($storage_definition);
     $this->multiple = FALSE;
     $this->limit_values = FALSE;
 
@@ -316,7 +316,7 @@ public function clickSort($order) {
     }
 
     $this->ensureMyTable();
-    $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']);
+    $field = $this->entityManager->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']];
     $column = ContentEntityDatabaseStorage::_fieldColumnName($field, $this->options['click_sort_column']);
     if (!isset($this->aliases[$column])) {
       // Column is not in query; add a sort on it (without adding the column).
@@ -329,7 +329,7 @@ protected function defineOptions() {
     $options = parent::defineOptions();
 
     // defineOptions runs before init/construct, so no $this->field_info
-    $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']);
+    $field = $this->entityManager->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']];
     $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->getType());
     $column_names = array_keys($field->getColumns());
     $default_column = '';
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php b/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php
index 6b0b153..d1d007f 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php
@@ -19,7 +19,7 @@
 class FieldList extends ManyToOne {
 
   public function getValueOptions() {
-    $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']);
+    $field = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']];
     $this->value_options = list_allowed_values($field);
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php b/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php
index 46db003..383ab40 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php
@@ -52,7 +52,7 @@ public static function create(ContainerInterface $container, array $configuratio
   public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
     parent::init($view, $display, $options);
 
-    $this->field_info = field_info_field($this->definition['entity_type'], $this->definition['field_name']);
+    $this->field_info = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']];
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
index 2b74370..542139e 100644
--- a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\ContentEntityDatabaseStorage;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\field\Entity\FieldInstanceConfig;
 use Drupal\field\FieldConfigInterface;
 
 
@@ -176,7 +177,7 @@ function testDeleteFieldInstance() {
     $this->assertEqual(count($found), 10, 'Correct number of entities found before deleting');
 
     // Delete the instance.
-    $instance = field_info_instance($this->entity_type, $field->name, $bundle);
+    $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name);
     $instance->delete();
 
     // The instance still exists, deleted.
@@ -226,7 +227,7 @@ function testPurgeInstance() {
     $field = reset($this->fields);
 
     // Delete the instance.
-    $instance = field_info_instance($this->entity_type, $field->name, $bundle);
+    $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name);
     $instance->delete();
 
     // No field hooks were called.
@@ -285,7 +286,7 @@ function testPurgeField() {
 
     // Delete the first instance.
     $bundle = reset($this->bundles);
-    $instance = field_info_instance($this->entity_type, $field->name, $bundle);
+    $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name);
     $instance->delete();
 
     // Assert that FieldItemInterface::delete() was not called yet.
@@ -315,7 +316,7 @@ function testPurgeField() {
 
     // Delete the second instance.
     $bundle = next($this->bundles);
-    $instance = field_info_instance($this->entity_type, $field->name, $bundle);
+    $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name);
     $instance->delete();
 
     // Assert that FieldItemInterface::delete() was not called yet.
diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
index 36a2770..4644b2c 100644
--- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\field\Tests;
 
 use Drupal\Core\Entity\EntityStorageException;
+use Drupal\field\Entity\FieldConfig;
 use Drupal\field\FieldException;
 
 class CrudTest extends FieldUnitTestBase {
@@ -312,7 +313,7 @@ function testDeleteField() {
     // Test that the first field is not deleted, and then delete it.
     $field = current(entity_load_multiple_by_properties('field_config', array('field_name' => $this->field['name'], 'include_deleted' => TRUE)));
     $this->assertTrue(!empty($field) && empty($field->deleted), 'A new field is not marked for deletion.');
-    field_info_field('entity_test', $this->field['name'])->delete();
+    FieldConfig::loadByName('entity_test', $this->field['name'])->delete();
 
     // Make sure that the field is marked as deleted when it is specifically
     // loaded.
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php
index a80df81..0bf7732 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\field\Tests;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Unit test class for storage-related field behavior.
@@ -337,7 +338,7 @@ function testEntityCreateRenameBundle() {
     entity_test_rename_bundle($this->instance_definition['bundle'], $new_bundle, $entity_type);
 
     // Check that the instance definition has been updated.
-    $this->instance = field_info_instance($entity_type, $this->field_name, $new_bundle);
+    $this->instance = FieldInstanceConfig::loadByName($entity_type, $new_bundle, $this->field_name);
     $this->assertIdentical($this->instance->bundle, $new_bundle, "Bundle name has been updated in the instance.");
 
     // Verify the field data is present on load.
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php
index f248fdc..7a1c4fb 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php
@@ -7,8 +7,6 @@
 
 namespace Drupal\field\Tests;
 
-use Drupal\field\Field;
-
 /**
  * Tests creating fields and instances as part of config import.
  */
@@ -60,13 +58,20 @@ function testImportCreateDefault() {
     $this->assertTrue($instance->bundle, 'test_bundle', 'The second field instance was created on bundle test_bundle.');
     $this->assertTrue($instance->bundle, 'test_bundle_2', 'The second field instance was created on bundle test_bundle_2.');
 
-    // Tests field info contains the right data.
-    $instances = Field::fieldInfo()->getInstances('entity_test');
-    $this->assertEqual(count($instances['entity_test']), 2);
-    $this->assertTrue(isset($instances['entity_test']['field_test_import']));
-    $this->assertTrue(isset($instances['entity_test']['field_test_import_2']));
-    $this->assertEqual(count($instances['test_bundle']), 1);
-    $this->assertTrue(isset($instances['test_bundle']['field_test_import_2']));
+    // Tests field instances.
+    $ids = \Drupal::entityQuery('field_instance_config')
+      ->condition('entity_type', 'entity_test')
+      ->condition('bundle', 'entity_test')
+      ->execute();
+    $this->assertEqual(count($ids), 2);
+    $this->assertTrue(isset($ids['entity_test.entity_test.field_test_import']));
+    $this->assertTrue(isset($ids['entity_test.entity_test.field_test_import_2']));
+    $ids = \Drupal::entityQuery('field_instance_config')
+      ->condition('entity_type', 'entity_test')
+      ->condition('bundle', 'test_bundle')
+      ->execute();
+    $this->assertEqual(count($ids), 1);
+    $this->assertTrue(isset($ids['entity_test.test_bundle.field_test_import_2']));
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
index f8a02ab..515301e 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php
@@ -8,6 +8,8 @@
 namespace Drupal\field\Tests;
 
 use Drupal\Core\Entity\EntityStorageException;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldInstanceConfig;
 use Drupal\field\FieldException;
 
 class FieldInstanceCrudTest extends FieldUnitTestBase {
@@ -188,8 +190,8 @@ function testDeleteFieldInstanceCrossDeletion() {
     entity_create('field_instance_config', $this->instance_definition)->save();
     entity_create('field_instance_config', $instance_definition_2)->save();
     $field->delete();
-    $this->assertFalse(field_info_instance('entity_test', $this->instance_definition['bundle'], $field->name));
-    $this->assertFalse(field_info_instance('entity_test', $instance_definition_2['bundle'], $field->name));
+    $this->assertFalse(FieldInstanceConfig::loadByName('entity_test', $this->instance_definition['bundle'], $field->name));
+    $this->assertFalse(FieldInstanceConfig::loadByName('entity_test', $instance_definition_2['bundle'], $field->name));
 
     // Chack that deletion of the last instance deletes the field.
     $field = entity_create('field_config', $this->field_definition);
@@ -199,9 +201,9 @@ function testDeleteFieldInstanceCrossDeletion() {
     $instance_2 = entity_create('field_instance_config', $instance_definition_2);
     $instance_2->save();
     $instance->delete();
-    $this->assertTrue(field_info_field('entity_test', $field->name));
+    $this->assertTrue(FieldConfig::loadByName('entity_test', $field->name));
     $instance_2->delete();
-    $this->assertFalse(field_info_field('entity_test', $field->name));
+    $this->assertFalse(FieldConfig::loadByName('entity_test', $field->name));
 
     // Check that deletion of all instances of the same field simultaneously
     // deletes the field.
@@ -213,7 +215,7 @@ function testDeleteFieldInstanceCrossDeletion() {
     $instance_2->save();
     $instance_storage = $this->container->get('entity.manager')->getStorage('field_instance_config');
     $instance_storage->delete(array($instance, $instance_2));
-    $this->assertFalse(field_info_field('entity_test', $field->name));
+    $this->assertFalse(FieldConfig::loadByName('entity_test', $field->name));
   }
 
 }
diff --git a/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php b/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php
index d8a43d4..7ab37dc 100644
--- a/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php
+++ b/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php
@@ -48,13 +48,6 @@ class FieldInstanceConfigEntityUnitTest extends UnitTestCase {
   protected $uuid;
 
   /**
-   * The field info provider.
-   *
-   * @var \Drupal\field\FieldInfo|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $fieldInfo;
-
-  /**
    * {@inheritdoc}
    */
   public static function getInfo() {
@@ -75,14 +68,9 @@ public function setUp() {
 
     $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
 
-    $this->fieldInfo = $this->getMockBuilder('\Drupal\field\FieldInfo')
-      ->disableOriginalConstructor()
-      ->getMock();
-
     $container = new ContainerBuilder();
     $container->set('entity.manager', $this->entityManager);
     $container->set('uuid', $this->uuid);
-    $container->set('field.info', $this->fieldInfo);
     \Drupal::setContainer($container);
 
   }
@@ -98,9 +86,12 @@ public function testCalculateDependencies() {
     $field->expects($this->once())
       ->method('getConfigDependencyName')
       ->will($this->returnValue('field.field.test_entity_type.test_field'));
-    $this->fieldInfo->expects($this->any())
-      ->method('getField')
-      ->with('test_entity_type', 'test_field')
+
+    $field_storage = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityStorageInterface');
+    $field_storage
+      ->expects($this->any())
+      ->method('load')
+      ->with('test_entity_type.test_field')
       ->will($this->returnValue($field));
 
     // Mock the interfaces necessary to create a dependency on a bundle entity.
@@ -118,8 +109,10 @@ public function testCalculateDependencies() {
 
     $this->entityManager->expects($this->any())
       ->method('getStorage')
-      ->with('bundle_entity_type')
-      ->will($this->returnValue($storage));
+      ->will($this->returnValueMap(array(
+        array('field_config', $field_storage),
+        array('bundle_entity_type', $storage),
+      )));
 
     $target_entity_type = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
     $target_entity_type->expects($this->any())
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
index eee9f27..dc37731 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php
@@ -424,7 +424,7 @@ public function submitForm(array &$form, array &$form_state) {
     if (!empty($form_values['_add_existing_field']['field_name'])) {
       $values = $form_values['_add_existing_field'];
       $field_name = $values['field_name'];
-      $field = field_info_field($this->entity_type, $field_name);
+      $field = FieldConfig::loadByName($this->entity_type, $field_name);
       if (!empty($field->locked)) {
         drupal_set_message($this->t('The field %label cannot be added because it is locked.', array('%label' => $values['label'])), 'error');
       }
@@ -531,16 +531,17 @@ protected function getExistingFieldOptions() {
    * Checks if a field machine name is taken.
    *
    * @param string $value
-   *   The machine name, not prefixed with 'field_'.
+   *   The machine name, not prefixed.
    *
    * @return bool
    *   Whether or not the field machine name is taken.
    */
   public function fieldNameExists($value) {
-    // Prefix with 'field_'.
-    $field_name = 'field_' . $value;
+    // Add the field prefix.
+    $field_name = \Drupal::config('field_ui.settings')->get('field_prefix') . $value;
 
-    return (bool) field_info_field($this->entity_type, $field_name);
+    $fields = \Drupal::entityManager()->getFieldStorageDefinitions($this->entity_type);
+    return isset($fields[$field_name]);
   }
 
 }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
index 3739368..b526c02 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\TypedData\TypedDataManager;
-use Drupal\field\FieldInfo;
 use Drupal\field\FieldInstanceConfigInterface;
 use Drupal\field_ui\FieldUI;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -35,13 +34,6 @@ class FieldEditForm extends FormBase {
   protected $entityManager;
 
   /**
-   * The field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * The typed data manager.
    *
    * @var \Drupal\Core\TypedData\TypedDataManager
@@ -60,14 +52,11 @@ public function getFormId() {
    *
    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
    *   The entity manager.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
    * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
    *   The typed data manager.
    */
-  public function __construct(EntityManagerInterface $entity_manager, FieldInfo $field_info, TypedDataManager $typed_data_manager) {
+  public function __construct(EntityManagerInterface $entity_manager, TypedDataManager $typed_data_manager) {
     $this->entityManager = $entity_manager;
-    $this->fieldInfo = $field_info;
     $this->typedDataManager = $typed_data_manager;
   }
 
@@ -77,7 +66,6 @@ public function __construct(EntityManagerInterface $entity_manager, FieldInfo $f
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager'),
-      $container->get('field.info'),
       $container->get('typed_data_manager')
     );
   }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
index 1b8c16d..e5850a7 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
@@ -311,10 +311,11 @@ function testSingleViewMode() {
    */
   function testNoFieldsDisplayOverview() {
     // Create a fresh content type without any fields.
-    $this->drupalCreateContentType(array('type' => 'no_fields', 'name' => 'No fields'));
-
-    // Remove the 'body' field.
-    field_info_instance('node', 'body', 'no_fields')->delete();
+    $this->drupalCreateContentType(array(
+      'type' => 'no_fields',
+      'name' => 'No fields',
+      'create_body' => FALSE,
+    ));
 
     $this->drupalGet('admin/structure/types/manage/no_fields/display');
     $this->assertRaw(t('There are no fields yet added. You can add new fields on the <a href="@link">Manage fields</a> page.', array('@link' => url('admin/structure/types/manage/no_fields/fields'))));
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 8fd993f..212df05 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -10,6 +10,8 @@
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Component\Utility\String;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Tests the functionality of the 'Manage fields' screen.
@@ -246,11 +248,11 @@ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string'
     // Reset the fields info.
     field_info_cache_clear();
     // Assert field settings.
-    $field = field_info_field($entity_type, $field_name);
+    $field = FieldConfig::loadByName($entity_type, $field_name);
     $this->assertTrue($field->getSetting('test_field_setting') == $string, 'Field settings were found.');
 
     // Assert instance settings.
-    $instance = field_info_instance($entity_type, $field_name, $bundle);
+    $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name);
     $this->assertTrue($instance->getSetting('test_instance_setting') == $string, 'Field instance settings were found.');
   }
 
@@ -322,7 +324,7 @@ function testDefaultValue() {
     $this->drupalPostForm($admin_path, $edit, t('Save settings'));
     $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.');
     field_info_cache_clear();
-    $instance = field_info_instance('node', $field_name, $this->type);
+    $instance = FieldInstanceConfig::loadByName('node', $this->type, $field_name);
     $this->assertEqual($instance->default_value, array(array('value' => 1)), 'The default value was correctly saved.');
 
     // Check that the default value shows up in the form
@@ -334,7 +336,7 @@ function testDefaultValue() {
     $this->drupalPostForm(NULL, $edit, t('Save settings'));
     $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.');
     field_info_cache_clear();
-    $instance = field_info_instance('node', $field_name, $this->type);
+    $instance = FieldInstanceConfig::loadByName('node', $this->type, $field_name);
     $this->assertEqual($instance->default_value, NULL, 'The default value was correctly saved.');
 
     // Check that the default widget is used when the field is hidden.
@@ -375,9 +377,9 @@ function testDeleteField() {
     // Reset the fields info.
     field_info_cache_clear();
     // Check that the field instance was deleted.
-    $this->assertNull(field_info_instance('node', $this->field_name, $this->type), 'Field instance was deleted.');
+    $this->assertNull(FieldInstanceConfig::loadByName('node', $this->type, $this->field_name), 'Field instance was deleted.');
     // Check that the field was not deleted
-    $this->assertNotNull(field_info_field('node', $this->field_name), 'Field was not deleted.');
+    $this->assertNotNull(FieldConfig::loadByName('node', $this->field_name), 'Field was not deleted.');
 
     // Delete the second instance.
     $this->fieldUIDeleteField($bundle_path2, "node.$type_name2.$this->field_name", $this->field_label, $type_name2);
@@ -385,9 +387,9 @@ function testDeleteField() {
     // Reset the fields info.
     field_info_cache_clear();
     // Check that the field instance was deleted.
-    $this->assertNull(field_info_instance('node', $this->field_name, $type_name2), 'Field instance was deleted.');
+    $this->assertNull(FieldInstanceConfig::loadByName('node', $type_name2, $this->field_name), 'Field instance was deleted.');
     // Check that the field was deleted too.
-    $this->assertNull(field_info_field('node', $this->field_name), 'Field was deleted.');
+    $this->assertNull(FieldConfig::loadByName('node', $this->field_name), 'Field was deleted.');
   }
 
   /**
@@ -407,13 +409,13 @@ function testDisallowedFieldNames() {
     $edit['fields[_add_new_field][field_name]'] = 'title';
     $bundle_path = 'admin/structure/types/manage/' . $this->type;
     $this->drupalPostForm("$bundle_path/fields",  $edit, t('Save'));
-    $this->assertText(t('There was a problem creating field Disallowed field: Attempt to create field title which is reserved by entity type node.', array('%label' => $label)), 'Field was not saved.');
+    $this->assertText(t('The machine-readable name is already in use. It must be unique.'));
 
     // Try with a base field.
     $edit['fields[_add_new_field][field_name]'] = 'sticky';
     $bundle_path = 'admin/structure/types/manage/' . $this->type;
     $this->drupalPostForm("$bundle_path/fields",  $edit, t('Save'));
-    $this->assertText(t('There was a problem creating field Disallowed field: Attempt to create field sticky which is reserved by entity type node.', array('%label' => $label)), 'Field was not saved.');
+    $this->assertText(t('The machine-readable name is already in use. It must be unique.'));
   }
 
   /**
@@ -554,9 +556,9 @@ function testDeleteTaxonomyField() {
     // Reset the fields info.
     field_info_cache_clear();
     // Check that the field instance was deleted.
-    $this->assertNull(field_info_instance('taxonomy_term', $this->field_name, 'tags'), 'Field instance was deleted.');
+    $this->assertNull(FieldInstanceConfig::loadByName('taxonomy_term', 'tags', $this->field_name), 'Field instance was deleted.');
     // Check that the field was deleted too.
-    $this->assertNull(field_info_field('taxonomy_term', $this->field_name), 'Field was deleted.');
+    $this->assertNull(FieldConfig::loadByName('taxonomy_term', $this->field_name), 'Field was deleted.');
   }
 
   /**
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 9fb3c60..b1c90dd 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -5,7 +5,10 @@
  * Defines a "managed_file" Form API field and a "file" field for Field module.
  */
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Render\Element;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\FieldConfigInterface;
 use Drupal\file\Entity\File;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Utility\Unicode;
@@ -647,8 +650,9 @@ function file_file_download($uri, $field_type = 'file') {
   // reference denied access, access is denied.
   foreach ($references as $field_name => $field_references) {
     foreach ($field_references as $entity_type => $entities) {
+      $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
       foreach ($entities as $entity) {
-        $field = field_info_field($entity_type, $field_name);
+        $field = $fields[$field_name];
         // Check if access to this field is not disallowed.
         if (!$entity->get($field_name)->access('view')) {
           $denied = TRUE;
@@ -1857,9 +1861,10 @@ function file_icon_map(File $file) {
  *
  * @param \Drupal\file\File $file
  *   A file entity.
- * @param $field
- *   (optional) A field array to be used for this check. If given, limits the
+ * @param \Drupal\field\FieldConfigInterface $field
+ *   (optional) A field definition to be used for this check. If given, limits the
  *   reference check to the given field.
+ *   @todo This should use FieldDefinitionInterface instead.
  * @param $age
  *   (optional) A constant that specifies which references to count. Use
  *   EntityStorageInterface::FIELD_LOAD_REVISION to retrieve all
@@ -1876,7 +1881,7 @@ function file_icon_map(File $file) {
  *   A multidimensional array. The keys are field_name, entity_type,
  *   entity_id and the value is an entity referencing this file.
  */
-function file_get_file_references(File $file, $field = NULL, $age = EntityStorageInterface::FIELD_LOAD_REVISION, $field_type = 'file') {
+function file_get_file_references(File $file, FieldConfigInterface $field = NULL, $age = EntityStorageInterface::FIELD_LOAD_REVISION, $field_type = 'file') {
   $references = &drupal_static(__FUNCTION__, array());
   $field_columns = &drupal_static(__FUNCTION__ . ':field_columns', array());
 
@@ -1938,7 +1943,7 @@ function file_get_file_references(File $file, $field = NULL, $age = EntityStorag
   if ($field || $field_type) {
     foreach ($return as $field_name => $data) {
       foreach (array_keys($data) as $entity_type_id) {
-        $current_field = field_info_field($entity_type_id, $field_name);
+        $current_field = FieldConfig::loadByName($entity_type_id, $field_name);
         if (($field_type && $current_field->getType() != $field_type) || ($field && $field->uuid() != $current_field->uuid())) {
           unset($return[$field_name][$entity_type_id]);
         }
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php
index 6426304..6be495c 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php
@@ -12,7 +12,6 @@
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Render\Element;
-use Drupal\field\Field;
 
 /**
  * Plugin implementation of the 'file_generic' widget.
@@ -311,18 +310,18 @@ public static function validateMultipleCount($element, &$form_state, $form) {
     array_pop($parents);
     $current = count(Element::children(NestedArray::getValue($form, $parents))) - 1;
 
-    $field = Field::fieldInfo()->getField($element['#entity_type'], $element['#field_name']);
+    $field = \Drupal::entityManager()->getFieldStorageDefinitions($element['#entity_type'])[$element['#field_name']];
     $uploaded = count($values['fids']);
     $count = $uploaded + $current;
-    if ($count > $field->cardinality) {
-      $keep = $uploaded - $count + $field->cardinality;
+    if ($count > $field->getCardinality()) {
+      $keep = $uploaded - $count + $field->getCardinality();
       $removed_files = array_slice($values['fids'], $keep);
       $removed_names = array();
       foreach ($removed_files as $fid) {
         $file = file_load($fid);
         $removed_names[] = $file->getFilename();
       }
-      $args = array('%field' => $field->getFieldName(), '@max' => $field->cardinality, '@count' => $keep, '%list' => implode(', ', $removed_names));
+      $args = array('%field' => $field->getFieldName(), '@max' => $field->getCardinality(), '@count' => $keep, '%list' => implode(', ', $removed_names));
       $message = t('Field %field can only hold @max values but there were @count uploaded. The following files have been omitted as a result: %list.', $args);
       drupal_set_message($message, 'warning');
       $values['fids'] = array_slice($values['fids'], 0, $keep);
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
index a7df01d..644f6f9 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\file\Tests;
 
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldInstanceConfig;
 use Drupal\file\FileInterface;
 use Drupal\simpletest\WebTestBase;
 
@@ -123,7 +125,7 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra
    * Updates an existing file field with new settings.
    */
   function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) {
-    $instance = field_info_instance('node', $name, $type_name);
+    $instance = FieldInstanceConfig::loadByName('node', $type_name, $name);
     $instance->settings = array_merge($instance->settings, $instance_settings);
     $instance->save();
 
@@ -159,7 +161,7 @@ function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE,
     }
 
     // Attach a file to the node.
-    $field = field_info_field('node', $field_name);
+    $field = FieldConfig::loadByName('node', $field_name);
     $name = 'files[' . $field_name . '_0]';
     if ($field->getCardinality() != 1) {
       $name .= '[]';
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
index b85b187..d35a491 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
@@ -8,7 +8,7 @@
 namespace Drupal\file\Tests;
 
 use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\field\Field;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Tests various validations.
@@ -32,7 +32,7 @@ function testRequired() {
     $type_name = 'article';
     $field_name = strtolower($this->randomName());
     $field = $this->createFileField($field_name, 'node', $type_name, array(), array('required' => '1'));
-    $instance = Field::fieldInfo()->getInstance('node', $type_name, $field_name);
+    $instance = FieldInstanceConfig::loadByName('node', $type_name, $field_name);
 
     $test_file = $this->getTestFile('text');
 
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
index bf80c17..416ea07 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\file\Tests;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Tests file field widget.
@@ -208,7 +209,7 @@ function testPrivateFileSetting() {
     $type_name = 'article';
     $field_name = strtolower($this->randomName());
     $this->createFileField($field_name, 'node', $type_name);
-    $instance = field_info_instance('node', $field_name, $type_name);
+    $instance = FieldInstanceConfig::loadByName('node', $type_name, $field_name);
 
     $test_file = $this->getTestFile('text');
 
diff --git a/core/modules/file/tests/file_module_test/file_module_test.module b/core/modules/file/tests/file_module_test/file_module_test.module
index 30a7664..e9d6010 100644
--- a/core/modules/file/tests/file_module_test/file_module_test.module
+++ b/core/modules/file/tests/file_module_test/file_module_test.module
@@ -75,10 +75,9 @@ function file_module_test_form_submit($form, &$form_state) {
  * Implements hook_file_download_access().
  */
 function file_module_test_file_download_access(FieldConfigInterface $field, EntityInterface $entity, File $file) {
-  $instance = field_info_instance($entity->getEntityTypeId(), $field->getName(), $entity->bundle());
+  $field_definitions = \Drupal::entityManager()->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle());
   // Allow the file to be downloaded only if the given arguments are correct.
-  // If any are wrong, $instance will be NULL.
-  if (empty($instance)) {
+  if (empty($field_definitions[$field->getName()])) {
     return FALSE;
   }
 }
diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install
index 7f975e9..dafedba 100644
--- a/core/modules/forum/forum.install
+++ b/core/modules/forum/forum.install
@@ -4,6 +4,7 @@
  * @file
  * Install, update, and uninstall functions for the Forum module.
  */
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Implements hook_install().
@@ -20,7 +21,7 @@ function forum_install() {
     // Create the 'taxonomy_forums' field if it doesn't already exist. If forum
     // is being enabled at the same time as taxonomy after both modules have been
     // enabled, the field might exist but still be marked inactive.
-    if (!field_info_field('node', 'taxonomy_forums')) {
+    if (!FieldConfig::loadByName('node', 'taxonomy_forums')) {
       entity_create('field_config', array(
         'name' => 'taxonomy_forums',
         'entity_type' => 'node',
@@ -92,15 +93,15 @@ function forum_install() {
  * Implements hook_uninstall().
  */
 function forum_uninstall() {
-  if ($field = field_info_field('node', 'taxonomy_forums')) {
+  if ($field = FieldConfig::loadByName('node', 'taxonomy_forums')) {
     $field->delete();
   }
 
-  if ($field = field_info_field('node', 'comment_forum')) {
+  if ($field = FieldConfig::loadByName('node', 'comment_forum')) {
     $field->delete();
   }
 
-  if ($field = field_info_field('taxonomy_term', 'forum_container')) {
+  if ($field = FieldConfig::loadByName('taxonomy_term', 'forum_container')) {
     $field->delete();
   }
 
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 5facc3c..ae2f9a8 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -9,7 +9,7 @@
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Component\Utility\String;
-use Drupal\field\Field;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Implements hook_help().
@@ -109,7 +109,7 @@ function forum_menu_local_tasks(&$data, $route_name) {
     $vid = \Drupal::config('forum.settings')->get('vocabulary');
     $links = array();
     // Loop through all bundles for forum taxonomy vocabulary field.
-    $field = Field::fieldInfo()->getField('node', 'taxonomy_forums');
+    $field = FieldConfig::loadByName('node', 'taxonomy_forums');
     foreach ($field->getBundles() as $type) {
       if (\Drupal::entityManager()->getAccessController('node')->createAccess($type)) {
         $links[$type] = array(
diff --git a/core/modules/forum/forum.services.yml b/core/modules/forum/forum.services.yml
index 3035062..68a135b 100644
--- a/core/modules/forum/forum.services.yml
+++ b/core/modules/forum/forum.services.yml
@@ -1,7 +1,7 @@
 services:
   forum_manager:
     class: Drupal\forum\ForumManager
-    arguments: ['@config.factory', '@entity.manager', '@database', '@field.info', '@string_translation']
+    arguments: ['@config.factory', '@entity.manager', '@database', '@string_translation']
   forum.breadcrumb.node:
     class: Drupal\forum\Breadcrumb\ForumNodeBreadcrumbBuilder
     arguments: ['@entity.manager', '@config.factory', '@forum_manager']
diff --git a/core/modules/forum/lib/Drupal/forum/ForumManager.php b/core/modules/forum/lib/Drupal/forum/ForumManager.php
index 388dd4a..85692ab 100644
--- a/core/modules/forum/lib/Drupal/forum/ForumManager.php
+++ b/core/modules/forum/lib/Drupal/forum/ForumManager.php
@@ -14,7 +14,6 @@
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\comment\CommentInterface;
-use Drupal\field\FieldInfo;
 use Drupal\node\NodeInterface;
 
 /**
@@ -99,13 +98,6 @@ class ForumManager extends DependencySerialization implements ForumManagerInterf
   protected $index;
 
   /**
-   * Field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * Translation manager service.
    *
    * @var \Drupal\Core\StringTranslation\TranslationInterface
@@ -121,16 +113,13 @@ class ForumManager extends DependencySerialization implements ForumManagerInterf
    *   The entity manager service.
    * @param \Drupal\Core\Database\Connection $connection
    *   The current database connection.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
    * @param \Drupal\Core\StringTranslation\TranslationInterface $translation_manager
    *   The translation manager service.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, EntityManagerInterface $entity_manager, Connection $connection, FieldInfo $field_info, TranslationInterface $translation_manager) {
+  public function __construct(ConfigFactoryInterface $config_factory, EntityManagerInterface $entity_manager, Connection $connection, TranslationInterface $translation_manager) {
     $this->configFactory = $config_factory;
     $this->entityManager = $entity_manager;
     $this->connection = $connection;
-    $this->fieldInfo = $field_info;
     $this->translationManager = $translation_manager;
   }
 
@@ -488,8 +477,8 @@ public function getParents($tid) {
    */
   public function checkNodeType(NodeInterface $node) {
     // Fetch information about the forum field.
-    $instances = $this->fieldInfo->getBundleInstances('node', $node->bundle());
-    return !empty($instances['taxonomy_forums']);
+    $field_definitions = $this->entityManager->getFieldDefinitions('node', $node->bundle());
+    return !empty($field_definitions['taxonomy_forums']);
   }
 
   /**
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php
index 1e4e9bd..130143f 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\comment\CommentInterface;
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
+use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -36,7 +37,7 @@ public static function getInfo() {
    */
   function testForumUninstallWithField() {
     // Ensure that the field exists before uninstallation.
-    $field = field_info_field('node', 'taxonomy_forums');
+    $field = FieldConfig::loadByName('node', 'taxonomy_forums');
     $this->assertNotNull($field, 'The taxonomy_forums field exists.');
 
     // Create a taxonomy term.
@@ -82,7 +83,7 @@ function testForumUninstallWithField() {
     $this->assertResponse(200);
 
     // Check that the field is now deleted.
-    $field = field_info_field('node', 'taxonomy_forums');
+    $field = FieldConfig::loadByName('node', 'taxonomy_forums');
     $this->assertNull($field, 'The taxonomy_forums field has been deleted.');
   }
 
@@ -92,12 +93,12 @@ function testForumUninstallWithField() {
    */
   function testForumUninstallWithoutField() {
     // Manually delete the taxonomy_forums field before module uninstallation.
-    $field = field_info_field('node', 'taxonomy_forums');
+    $field = FieldConfig::loadByName('node', 'taxonomy_forums');
     $this->assertNotNull($field, 'The taxonomy_forums field exists.');
     $field->delete();
 
     // Check that the field is now deleted.
-    $field = field_info_field('node', 'taxonomy_forums');
+    $field = FieldConfig::loadByName('node', 'taxonomy_forums');
     $this->assertNull($field, 'The taxonomy_forums field has been deleted.');
 
     // Ensure that uninstallation succeeds even if the field has already been
diff --git a/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php b/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php
index e1d4a0a..c49a604 100644
--- a/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php
+++ b/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php
@@ -70,15 +70,10 @@ public function testGetIndex() {
       ->disableOriginalConstructor()
       ->getMock();
 
-    $field_info = $this->getMockBuilder('\Drupal\field\FieldInfo')
-      ->disableOriginalConstructor()
-      ->getMock();
-
     $manager = $this->getMock('\Drupal\forum\ForumManager', array('getChildren'), array(
       $config_factory,
       $entity_manager,
       $connection,
-      $field_info,
       $translation_manager,
     ));
 
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index b49a4ac..dd9ae7c 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\image\Tests;
 
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Test class to check that formatters and display settings are working.
@@ -271,7 +272,7 @@ function testImageFieldDefaultImage() {
     $this->drupalPostForm("admin/structure/types/manage/article/fields/node.article.$field_name/field", $edit, t('Save field settings'));
     // Clear field info cache so the new default image is detected.
     field_info_cache_clear();
-    $field = field_info_field('node', $field_name);
+    $field = FieldConfig::loadByName('node', $field_name);
     $default_image = $field->getSetting('default_image');
     $file = file_load($default_image['fid']);
     $this->assertTrue($file->isPermanent(), 'The default image status is permanent.');
@@ -309,7 +310,7 @@ function testImageFieldDefaultImage() {
     $this->drupalPostForm("admin/structure/types/manage/article/fields/node.article.$field_name/field", $edit, t('Save field settings'));
     // Clear field info cache so the new default image is detected.
     field_info_cache_clear();
-    $field = field_info_field('node', $field_name);
+    $field = FieldConfig::loadByName('node', $field_name);
     $default_image = $field->getSetting('default_image');
     $this->assertFalse($default_image['fid'], 'Default image removed from field.');
     // Create an image field that uses the private:// scheme and test that the
@@ -326,7 +327,7 @@ function testImageFieldDefaultImage() {
     // Clear field info cache so the new default image is detected.
     field_info_cache_clear();
 
-    $private_field = field_info_field('node', $private_field_name);
+    $private_field = FieldConfig::loadByName('node', $private_field_name);
     $default_image = $private_field->getSetting('default_image');
     $file = file_load($default_image['fid']);
     $this->assertEqual('private', file_uri_scheme($file->getFileUri()), 'Default image uses private:// scheme.');
diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php
index 0fe3b86..4cefa2f 100644
--- a/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php
+++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php
@@ -6,7 +6,7 @@
 
 namespace Drupal\migrate\Plugin;
 
-use Drupal\field\Entity\FieldInstance;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Handle the importing of a specific configurable field type.
@@ -16,14 +16,15 @@
   /**
    * Convert an array of values into an array structure fit for entity_create.
    *
-   * @param \Drupal\field\Entity\FieldInstance $instance
-   *   The field instance. For example, this can be used to check for required.
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The field definition. For example, this can be used to check for
+   *   required values.
    * @param array $values
    *   The array of values.
    * @return array|NULL
    *   This will be set in the $values array passed to entity_create() as the
    *   value of a configurable field of the type this class handles.
    */
-  public function import(FieldInstance $instance, array $values = NULL);
+  public function import(FieldDefinitionInterface $field_definition, array $values = NULL);
 
 }
diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php
index cd3b11e..885a6ea 100644
--- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php
+++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\KeyValueStore\StateInterface;
-use Drupal\field\FieldInfo;
 use Drupal\migrate\Entity\MigrationInterface;
 use Drupal\migrate\Plugin\MigratePluginManager;
 use Drupal\migrate\Row;
@@ -46,13 +45,13 @@ class EntityComment extends EntityContentBase {
    *   The list of bundles this entity type has.
    * @param \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager
    *   The migrate plugin manager.
-   * @param \Drupal\field\FieldInfo $field_info
+   * @param \Drupal\field\FieldInfo $entity_manager
    *   The field and instance definitions service.
-   * @param \Drupal\Core\KeyValueStore\StateInterface $state
-   *   The state storage object.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info, StateInterface $state) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $field_info);
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $entity_manager, StateInterface $state) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $entity_manager);
     $this->state = $state;
   }
 
@@ -69,7 +68,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $container->get('entity.manager')->getStorage($entity_type),
       array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
       $container->get('plugin.manager.migrate.entity_field'),
-      $container->get('field.info'),
+      $container->get('entity.manager'),
       $container->get('state')
     );
   }
diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php
index 8692947..f73bf10 100644
--- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php
+++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php
@@ -9,9 +9,9 @@
 
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
-use Drupal\field\FieldInfo;
 use Drupal\migrate\Entity\MigrationInterface;
 use Drupal\migrate\Plugin\MigratePluginManager;
 use Drupal\migrate\Row;
@@ -23,9 +23,11 @@
 class EntityContentBase extends Entity {
 
   /**
-   * @var \Drupal\field\FieldInfo
+   * Entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $fieldInfo;
+  protected $entityManager;
 
   /**
    * Constructs a content entity.
@@ -44,13 +46,13 @@ class EntityContentBase extends Entity {
    *   The list of bundles this entity type has.
    * @param \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager
    *   The plugin manager.
-   * @param \Drupal\Field\FieldInfo $field_info
-   *   The field info.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, EntityManagerInterface $entity_manager) {
     parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles);
     $this->migrateEntityFieldPluginManager = $plugin_manager;
-    $this->fieldInfo = $field_info;
+    $this->entityManager = $entity_manager;
   }
 
   /**
@@ -66,7 +68,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $container->get('entity.manager')->getStorage($entity_type),
       array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
       $container->get('plugin.manager.migrate.entity_field'),
-      $container->get('field.info')
+      $container->get('entity.manager')
     );
   }
 
@@ -74,23 +76,20 @@ public static function create(ContainerInterface $container, array $configuratio
    * {@inheritdoc}
    */
   public function import(Row $row, array $old_destination_id_values = array()) {
-    if ($all_instances = $this->fieldInfo->getInstances($this->storage->getEntityTypeId())) {
-      /** @var \Drupal\Field\Entity\FieldInstanceConfig[] $instances */
-      $instances = array();
-      if ($bundle_key = $this->getKey('bundle')) {
-        $bundle = $row->getDestinationProperty($bundle_key);
-        if (isset($all_instances[$bundle])) {
-          $instances = $all_instances[$bundle];
-        }
-      }
-      foreach ($instances as $field_name => $instance) {
-        $field_type = $instance->getType();
-        if ($this->migrateEntityFieldPluginManager->getDefinition($field_type)) {
-          $destination_value = $this->migrateEntityFieldPluginManager->createInstance($field_type)->import($instance, $row->getDestinationProperty($field_name));
-          // @TODO: check for NULL return? Add an unset to $row? Maybe needed in
-          // exception handling? Propagate exception?
-          $row->setDestinationProperty($field_name, $destination_value);
-        }
+    if ($bundle_key = $this->getKey('bundle')) {
+      $bundle = $row->getDestinationProperty($bundle_key);
+    }
+    else {
+      $bundle = $this->storage->getEntityTypeId();
+    }
+    $field_definitions = $this->entityManager->getFieldDefinitions($this->storage->getEntityTypeId(), $bundle);
+    foreach ($field_definitions as $field_name => $field_definition) {
+      $field_type = $field_definition->getType();
+      if ($this->migrateEntityFieldPluginManager->getDefinition($field_type)) {
+        $destination_value = $this->migrateEntityFieldPluginManager->createInstance($field_type)->import($field_definition, $row->getDestinationProperty($field_name));
+        // @TODO: check for NULL return? Add an unset to $row? Maybe needed in
+        // exception handling? Propagate exception?
+        $row->setDestinationProperty($field_name, $destination_value);
       }
     }
     $entity = $this->getEntity($row, $old_destination_id_values);
diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php
index 6ae4f30..6703f56 100644
--- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php
+++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\migrate\Plugin\migrate\destination;
 
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\field\FieldInfo;
 use Drupal\migrate\Entity\MigrationInterface;
 use Drupal\migrate\Plugin\MigratePluginManager;
 use Drupal\migrate\Row;
@@ -23,14 +23,14 @@ class EntityFile extends EntityContentBase {
   /**
    * {@inheritdoc}
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, EntityManagerInterface $entity_manager) {
     $configuration += array(
       'source_base_path' => '',
       'source_path_property' => 'filepath',
       'destination_path_property' => 'uri',
       'move' => FALSE,
     );
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $field_info);
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $entity_manager);
   }
 
   /**
diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php
index f8495ba..5cdcfc6 100644
--- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php
+++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\migrate\Plugin\migrate\destination;
 
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Password\PasswordInterface;
-use Drupal\field\FieldInfo;
 use Drupal\migrate\Entity\MigrationInterface;
 use Drupal\migrate\MigrateException;
 use Drupal\migrate\MigratePassword;
@@ -48,13 +48,13 @@ class EntityUser extends EntityContentBase {
    *   The list of bundles this entity type has.
    * @param \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager
    *   The migrate plugin manager.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field and instance definitions service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    * @param \Drupal\Core\Password\PasswordInterface $password
    *   The password service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info, PasswordInterface $password) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $field_info);
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, EntityManagerInterface $entity_manager, PasswordInterface $password) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $entity_manager);
     if (isset($configuration['md5_passwords'])) {
       $this->password = $password;
     }
@@ -73,7 +73,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $container->get('entity.manager')->getStorage($entity_type),
       array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
       $container->get('plugin.manager.migrate.entity_field'),
-      $container->get('field.info'),
+      $container->get('entity.manager'),
       $container->get('password')
     );
   }
diff --git a/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php b/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php
index 1d59ca1..4ae1923 100644
--- a/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\node\Tests\Config;
 
+use Drupal\field\Entity\FieldInstanceConfig;
 use Drupal\simpletest\DrupalUnitTestBase;
 
 /**
@@ -80,7 +81,7 @@ public function testImportCreate() {
     // Check that the content type was created.
     $node_type = entity_load('node_type', $node_type_id);
     $this->assertTrue($node_type, 'Import node type from staging was created.');
-    $this->assertFalse(field_info_instance('node', 'body', $node_type_id));
+    $this->assertFalse(FieldInstanceConfig::loadByName('node', $node_type_id, 'body'));
   }
 
 }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
index 67b34e7..fd83b93 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\node\Tests;
 
+use Drupal\field\Entity\FieldConfig;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
 use Drupal\simpletest\WebTestBase;
 use Drupal\Core\Language\Language;
@@ -60,7 +61,7 @@ function setUp() {
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.');
 
     // Make node body translatable.
-    $field = field_info_field('node', 'body');
+    $field = FieldConfig::loadByName('node', 'body');
     $field->translatable = TRUE;
     $field->save();
   }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
index 6cfc32f..4b6ac42 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\node\Tests;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Tests related to node types.
@@ -83,7 +84,7 @@ function testNodeTypeEditing() {
     $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types', 'administer node fields'));
     $this->drupalLogin($web_user);
 
-    $instance = field_info_instance('node', 'body', 'page');
+    $instance = FieldInstanceConfig::loadByName('node', 'page', 'body');
     $this->assertEqual($instance->getLabel(), 'Body', 'Body field was found.');
 
     // Verify that title and body fields are displayed.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 6b77d21..fc8d6e6 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -12,6 +12,8 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Url;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldInstanceConfig;
 use Symfony\Component\HttpFoundation\Response;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Database\Query\AlterableInterface;
@@ -394,8 +396,8 @@ function node_type_load($name) {
  */
 function node_add_body_field(NodeTypeInterface $type, $label = 'Body') {
    // Add or remove the body field, as needed.
-  $field = field_info_field('node', 'body');
-  $instance = field_info_instance('node', 'body', $type->id());
+  $field = FieldConfig::loadByName('node', 'body');
+  $instance = FieldInstanceConfig::loadByName('node', $type->id(), 'body');
   if (empty($field)) {
     $field = entity_create('field_config', array(
       'name' => 'body',
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index e06da3f..8789047 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -131,10 +131,9 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
         case 'body':
         case 'summary':
           $translation = \Drupal::entityManager()->getTranslationFromContext($node, $langcode, array('operation' => 'node_tokens'));
-          if (($items = $translation->get('body')) && !$items->isEmpty()) {
+          if ($translation->hasField('body') && ($items = $translation->get('body')) && !$items->isEmpty()) {
             $item = $items[0];
-            $instance = field_info_instance('node', 'body', $node->getType());
-            $field_langcode = $translation->language()->id;
+            $field_definition = \Drupal::entityManager()->getFieldDefinitions('node', $node->bundle())['body'];
             // If the summary was requested and is not empty, use it.
             if ($name == 'summary' && !empty($item->summary)) {
               $output = $sanitize ? $item->summary_processed : $item->summary;
@@ -157,7 +156,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
                   $length = $settings['trim_length'];
                 }
 
-                $output = text_summary($output, $instance->getSetting('text_processing') ? $item->format : NULL, $length);
+                $output = text_summary($output, $field_definition->getSetting('text_processing') ? $item->format : NULL, $length);
               }
             }
             $replacements[$original] = $output;
diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
index dd6d13e..d4f99ec 100644
--- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
+++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\options\Tests;
 
+use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Tests\FieldTestBase;
 
 /**
@@ -231,7 +232,7 @@ function testOptionsAllowedValuesBoolean() {
     $this->drupalGet($this->admin_path);
     $this->assertFieldByName('on', $on, t("The 'On' value is stored correctly."));
     $this->assertFieldByName('off', $off, t("The 'Off' value is stored correctly."));
-    $field = field_info_field('node', $this->field_name);
+    $field = FieldConfig::loadByName('node', $this->field_name);
     $this->assertEqual($field->getSetting('allowed_values'), $allowed_values, 'The allowed value is correct');
     $this->assertNull($field->getSetting('on'), 'The on value is not saved into settings');
     $this->assertNull($field->getSetting('off'), 'The off value is not saved into settings');
@@ -295,7 +296,7 @@ function assertAllowedValuesInput($input_string, $result, $message) {
     }
     else {
       field_info_cache_clear();
-      $field = field_info_field('node', $this->field_name);
+      $field = FieldConfig::loadByName('node', $this->field_name);
       $this->assertIdentical($field->getSetting('allowed_values'), $result, $message);
     }
   }
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
index a2fcbb7..1ffb010 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\path\Tests;
 
-use Drupal\field\Field;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Tests URL aliases for translated nodes.
@@ -67,9 +67,7 @@ function setUp() {
     );
     $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save'));
 
-    // Ensure configuration changes are picked up in the host environment.
-    Field::fieldInfo()->flush();
-    $field = Field::fieldInfo()->getField('node', 'body');
+    $field = FieldConfig::loadByName('node', 'body');
     $this->assertTrue($field->isTranslatable(), 'Node body is translatable.');
   }
 
diff --git a/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php b/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php
index d981936..2c1c093 100644
--- a/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php
+++ b/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php
@@ -14,7 +14,6 @@
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\field\FieldInfo;
 use Drupal\quickedit\Ajax\FieldFormCommand;
 use Drupal\quickedit\Ajax\FieldFormSavedCommand;
 use Drupal\quickedit\Ajax\FieldFormValidationErrorsCommand;
@@ -48,13 +47,6 @@ class QuickEditController extends ControllerBase {
   protected $editorSelector;
 
   /**
-   * The field info service.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * Constructs a new QuickEditController.
    *
    * @param \Drupal\user\TempStoreFactory $temp_store_factory
@@ -63,14 +55,11 @@ class QuickEditController extends ControllerBase {
    *   The in-place editing metadata generator.
    * @param \Drupal\quickedit\EditorSelectorInterface $editor_selector
    *   The in-place editor selector.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
    */
-  public function __construct(TempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector, FieldInfo $field_info) {
+  public function __construct(TempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector) {
     $this->tempStoreFactory = $temp_store_factory;
     $this->metadataGenerator = $metadata_generator;
     $this->editorSelector = $editor_selector;
-    $this->fieldInfo = $field_info;
   }
 
   /**
@@ -80,8 +69,7 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('user.tempstore'),
       $container->get('quickedit.metadata.generator'),
-      $container->get('quickedit.editor.selector'),
-      $container->get('field.info')
+      $container->get('quickedit.editor.selector')
     );
   }
 
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php
index b470ae6..b18290d 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php
@@ -8,7 +8,7 @@
 namespace Drupal\search\Tests;
 
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
-use Drupal\field\Field;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Test integration searching comments.
@@ -61,7 +61,7 @@ function testSearchResultsComment() {
     $comment_body = 'Test comment body';
 
     // Make preview optional.
-    $instance = Field::fieldInfo()->getInstance('node', 'article', 'comment');
+    $instance = FieldInstanceConfig::loadByName('node', 'article', 'comment');
     $instance->settings['preview'] = DRUPAL_OPTIONAL;
     $instance->save();
     // Enable check_plain() for 'Basic HTML' text format.
@@ -138,7 +138,7 @@ function testSearchResultsCommentAccess() {
 
     // Create a node.
     // Make preview optional.
-    $instance = Field::fieldInfo()->getInstance('node', 'article', 'comment');
+    $instance = FieldInstanceConfig::loadByName('node', 'article', 'comment');
     $instance->settings['preview'] = DRUPAL_OPTIONAL;
     $instance->save();
     $this->node = $this->drupalCreateNode(array('type' => 'article'));
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php
index 8dcec89..6897ba3 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php
@@ -8,7 +8,7 @@
 namespace Drupal\search\Tests;
 
 use Drupal\Core\Language\Language;
-use Drupal\field\Field;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Test node search with multiple languages.
@@ -47,7 +47,7 @@ function setUp() {
     // Make the body field translatable. The title is already translatable by
     // definition. The parent class has already created the article and page
     // content types.
-    $field = Field::fieldInfo()->getField('node', 'body');
+    $field = FieldConfig::loadByName('node', 'body');
     $field->translatable = TRUE;
     $field->save();
 
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php
index 37e00e8..1b670bf 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php
@@ -8,7 +8,7 @@
 namespace Drupal\search\Tests;
 
 use Drupal\Core\Language\Language;
-use Drupal\field\Field;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Tests entities with multilingual fields.
@@ -58,7 +58,7 @@ function setUp() {
     // Make the body field translatable. The title is already translatable by
     // definition. The parent class has already created the article and page
     // content types.
-    $field = Field::fieldInfo()->getField('node', 'body');
+    $field = FieldConfig::loadByName('node', 'body');
     $field->translatable = TRUE;
     $field->save();
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
index 4a05431..a838d2f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
@@ -17,6 +17,7 @@
 use Drupal\Core\TypedData\DataDefinitionInterface;
 use Drupal\Core\TypedData\Type\StringInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Tests Entity API base functionality.
@@ -623,7 +624,7 @@ public function testComputedProperties() {
    */
   protected function assertComputedProperties($entity_type) {
     // Make the test text field processed.
-    $instance = field_info_instance($entity_type, 'field_test_text', $entity_type);
+    $instance = FieldInstanceConfig::loadByName($entity_type, $entity_type, 'field_test_text');
     $instance->settings['text_processing'] = 1;
     $instance->save();
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php
index bd2ceb9..ada2fbd 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php
@@ -8,7 +8,7 @@
 namespace Drupal\system\Tests\Entity;
 
 use Drupal\Core\Language\Language;
-use Drupal\field\Field as FieldService;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Base class for language-aware entity tests.
@@ -133,12 +133,11 @@ function setUp() {
   protected function toggleFieldTranslatability($entity_type) {
     $fields = array($this->field_name, $this->untranslatable_field_name);
     foreach ($fields as $field_name) {
-      $field = FieldService::fieldInfo()->getField($entity_type, $field_name);
+      $field = FieldConfig::loadByName($entity_type, $field_name);
       $translatable = !$field->isTranslatable();
       $field->set('translatable', $translatable);
       $field->save();
-      FieldService::fieldInfo()->flush();
-      $field = FieldService::fieldInfo()->getField($entity_type, $field_name);
+      $field = FieldConfig::loadByName($entity_type, $field_name);
       $this->assertEqual($field->isTranslatable(), $translatable, 'Field translatability changed.');
     }
     \Drupal::cache('entity')->deleteAll();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
index 46b81bf..8c0288e 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Entity;
 
+use Drupal\field\Entity\FieldConfig;
 use Drupal\simpletest\WebTestBase;
 use Drupal\Core\Language\Language;
 
@@ -102,10 +103,10 @@ function testEntityFormLanguage() {
     $this->assertTrue($node, 'Node found in database.');
 
     // Make body translatable.
-    $field = field_info_field('node', 'body');
+    $field = FieldConfig::loadByName('node', 'body');
     $field->translatable = TRUE;
     $field->save();
-    $field = field_info_field('node', 'body');
+    $field = FieldConfig::loadByName('node', 'body');
     $this->assertTrue($field->isTranslatable(), 'Field body is translatable.');
 
     // Create a body translation and check the form language.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php
index 82e63b2..8549d99 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php
@@ -445,7 +445,7 @@ function testFieldSqlStorageForeignKeys() {
     $schema = $field->getSchema();
 
     // Retrieve the field definition and check that the foreign key is in place.
-    $field = field_info_field('entity_test', $field_name);
+    $field = FieldConfig::loadByName('entity_test', $field_name);
     $this->assertEqual($schema['foreign keys'][$foreign_key_name]['table'], $foreign_key_name, 'Foreign key table name modified after update');
     $this->assertEqual($schema['foreign keys'][$foreign_key_name]['columns'][$foreign_key_name], 'id', 'Foreign key column name modified after update');
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php
index 2e68569..b9d8cec 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php
@@ -10,7 +10,7 @@
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\ContentEntityDatabaseStorage;
 use Drupal\Core\Language\Language;
-use Drupal\field\Field as FieldService;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Tests entity translation.
@@ -91,7 +91,7 @@ protected function assertFieldStorageLangcode(ContentEntityInterface $entity, $m
     $fields = array($this->field_name, $this->untranslatable_field_name);
 
     foreach ($fields as $field_name) {
-      $field = FieldService::fieldInfo()->getField($entity_type, $field_name);
+      $field = FieldConfig::loadByName($entity_type, $field_name);
       $tables = array(
         ContentEntityDatabaseStorage::_fieldTableName($field),
         ContentEntityDatabaseStorage::_fieldRevisionTableName($field),
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php
index ab1db7d..d6534f8 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php
@@ -11,9 +11,8 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\String;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
-use Drupal\field\FieldInfo;
-use Drupal\taxonomy\TermStorageInterface;
 use Drupal\taxonomy\VocabularyInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
@@ -33,33 +32,23 @@ class TermAutocompleteController implements ContainerInjectionInterface {
   protected $termEntityQuery;
 
   /**
-   * Field info service.
+   * Entity manager.
    *
-   * @var \Drupal\field\FieldInfo
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $fieldInfo;
-
-  /**
-   * Term storage.
-   *
-   * @var \Drupal\taxonomy\TermStorageInterface
-   */
-  protected $termStorage;
+  protected $entityManager;
 
   /**
    * Constructs a new \Drupal\taxonomy\Controller\TermAutocompleteController object.
    *
    * @param \Drupal\Core\Entity\Query\QueryInterface $term_entity_query
    *   The entity query service.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
-   * @param \Drupal\taxonomy\TermStorageInterface $term_storage
-   *   The term storage.
+   * @param \Drupal\Core\Entity\EntityManagerInterface
+   *   The entity manager.
    */
-  public function __construct(QueryInterface $term_entity_query, FieldInfo $field_info, TermStorageInterface $term_storage) {
+  public function __construct(QueryInterface $term_entity_query, EntityManagerInterface $entity_manager) {
     $this->termEntityQuery = $term_entity_query;
-    $this->fieldInfo = $field_info;
-    $this->termStorage = $term_storage;
+    $this->entityManager = $entity_manager;
   }
 
   /**
@@ -68,8 +57,7 @@ public function __construct(QueryInterface $term_entity_query, FieldInfo $field_
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.query')->get('taxonomy_term'),
-      $container->get('field.info'),
-      $container->get('entity.manager')->getStorage('taxonomy_term')
+      $container->get('entity.manager')
     );
   }
 
@@ -110,11 +98,14 @@ public function autocomplete(Request $request, $entity_type, $field_name) {
     $tags_typed = $request->query->get('q');
 
     // Make sure the field exists and is a taxonomy field.
-    if (!($field = $this->fieldInfo->getField($entity_type, $field_name)) || $field->getType() !== 'taxonomy_term_reference') {
+    $field_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type);
+
+    if (!isset($field_definitions[$field_name]) || $field_definitions[$field_name]->getType() !== 'taxonomy_term_reference') {
       // Error string. The JavaScript handler will realize this is not JSON and
       // will display it as debugging information.
       return new Response(t('Taxonomy field @field_name not found.', array('@field_name' => $field_name)), 403);
     }
+    $field = $field_definitions[$field_name];
 
     // The user enters a comma-separated list of tags. We only autocomplete the
     // last tag.
@@ -193,7 +184,7 @@ protected function getMatchingTerms($tags_typed, array $vids, $tag_last) {
 
     $prefix = count($tags_typed) ? Tags::implode($tags_typed) . ', ' : '';
     if (!empty($tids)) {
-      $terms = $this->termStorage->loadMultiple(array_keys($tids));
+      $terms = $this->entityManager->getStorage('taxonomy_term')->loadMultiple(array_keys($tids));
       foreach ($terms as $term) {
         // Term names containing commas or quotes must be wrapped in quotes.
         $name = Tags::encode($term->getName());
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
index ec46b6b..6659ba3 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php
@@ -106,7 +106,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
       // Reflect machine name changes in the definitions of existing 'taxonomy'
       // fields.
       $field_ids = array();
-      $field_map = Field::fieldInfo()->getFieldMap();
+      $field_map = \Drupal::entityManager()->getFieldMap();
       foreach ($field_map as $entity_type => $fields) {
         foreach ($fields as $field => $info) {
           if ($info['type'] == 'taxonomy_term_reference') {
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
index afac0db..8ec55e7 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\taxonomy\Tests;
 
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Tests a taxonomy term reference field that allows multiple vocabularies.
@@ -122,7 +123,7 @@ function testTaxonomyTermFieldMultipleVocabularies() {
     $this->assertNoText($term2->getName(), 'Term 2 name is not displayed.');
 
     // Verify that field and instance settings are correct.
-    $field = field_info_field('entity_test', $this->field_name);
+    $field = FieldConfig::loadByName('entity_test', $this->field_name);
     $this->assertEqual(count($field->getSetting('allowed_values')), 1, 'Only one vocabulary is allowed for the field.');
 
     // The widget should still be displayed.
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
index 1dd0aab..f61b91e 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\taxonomy\Tests;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Tests for taxonomy term field and formatter.
@@ -170,7 +171,7 @@ function testTaxonomyTermFieldChangeMachineName() {
     $this->vocabulary->save();
 
     // Check that the field instance is still attached to the vocabulary.
-    $field = field_info_field('entity_test', $this->field_name);
+    $field = FieldConfig::loadByName('entity_test', $this->field_name);
     $allowed_values = $field->getSetting('allowed_values');
     $this->assertEqual($allowed_values[0]['vocabulary'], $new_name, 'Index 0: Machine name was updated correctly.');
     $this->assertEqual($allowed_values[1]['vocabulary'], $new_name, 'Index 1: Machine name was updated correctly.');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index d07ab4a..8863c42 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\Tags;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Component\Utility\String;
+use Drupal\field\Entity\FieldConfig;
 
 /**
  * Tests for taxonomy term functions.
@@ -235,7 +236,7 @@ function testNodeTermCreationAndDeletion() {
     $field_name = $this->randomName();
     $tag = $this->randomName();
     $message = t("Taxonomy field @field_name not found.", array('@field_name' => $field_name));
-    $this->assertFalse(field_info_field('node', $field_name), format_string('Field %field_name does not exist.', array('%field_name' => $field_name)));
+    $this->assertFalse(FieldConfig::loadByName('node', $field_name), format_string('Field %field_name does not exist.', array('%field_name' => $field_name)));
     $this->drupalGet('taxonomy/autocomplete/node/' . $field_name, array('query' => array('q' => $tag)));
     $this->assertRaw($message, 'Autocomplete returns correct error message when the taxonomy field does not exist.');
   }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php
index ae757f3..1d640ae 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\taxonomy\Tests;
+use Drupal\field\Entity\FieldInstanceConfig;
 
 /**
  * Tests for taxonomy vocabulary functions.
@@ -168,7 +169,7 @@ function testTaxonomyVocabularyChangeMachineName() {
     $this->assertTrue(isset($info[$new_name]), 'The new bundle name appears in entity_get_bundles().');
 
     // Check that the field instance is still attached to the vocabulary.
-    $this->assertTrue(field_info_instance('taxonomy_term', 'field_test', $new_name), 'The bundle name was updated correctly.');
+    $this->assertTrue(FieldInstanceConfig::loadByName('taxonomy_term', $new_name, 'field_test'), 'The bundle name was updated correctly.');
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/UserStorage.php b/core/modules/user/lib/Drupal/user/UserStorage.php
index d3f4990..78c48ff 100644
--- a/core/modules/user/lib/Drupal/user/UserStorage.php
+++ b/core/modules/user/lib/Drupal/user/UserStorage.php
@@ -9,11 +9,10 @@
 
 use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Password\PasswordInterface;
 use Drupal\Core\Database\Connection;
-use Drupal\field\FieldInfo;
-use Drupal\user\UserDataInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Core\Entity\ContentEntityDatabaseStorage;
 
@@ -46,8 +45,8 @@ class UserStorage extends ContentEntityDatabaseStorage implements UserStorageInt
    *   The entity type definition.
    * @param \Drupal\Core\Database\Connection $database
    *   The database connection to be used.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
    * @param \Drupal\Component\Uuid\UuidInterface $uuid_service
    *   The UUID Service.
    * @param \Drupal\Core\Password\PasswordInterface $password
@@ -55,8 +54,8 @@ class UserStorage extends ContentEntityDatabaseStorage implements UserStorageInt
    * @param \Drupal\user\UserDataInterface $user_data
    *   The user data service.
    */
-  public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info, UuidInterface $uuid_service, PasswordInterface $password, UserDataInterface $user_data) {
-    parent::__construct($entity_type, $database, $field_info, $uuid_service);
+  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, UuidInterface $uuid_service, PasswordInterface $password, UserDataInterface $user_data) {
+    parent::__construct($entity_type, $database, $entity_manager, $uuid_service);
 
     $this->password = $password;
     $this->userData = $user_data;
@@ -69,7 +68,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
     return new static(
       $entity_type,
       $container->get('database'),
-      $container->get('field.info'),
+      $container->get('entity.manager'),
       $container->get('uuid'),
       $container->get('password'),
       $container->get('user.data')
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 97515a2..0527cb4 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -5,9 +5,6 @@
  * Install, update and uninstall functions for the user module.
  */
 
-use Drupal\Core\Language\Language;
-use Drupal\field\Field;
-
 /**
  * Implements hook_schema().
  */
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 9dd87e8..23af29d 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -199,7 +199,8 @@ function user_attach_accounts(array $entities) {
  * preprocess stage.
  */
 function user_picture_enabled() {
-  return (bool) field_info_instance('user', 'user_picture', 'user');
+  $field_definitions = \Drupal::entityManager()->getFieldDefinitions('user', 'user');
+  return isset($field_definitions['user_picture']);
 }
 
 /**
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index ca14056..930c569 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -225,7 +225,7 @@ function views_ui_taxonomy_autocomplete_validate($element, &$form_state) {
   if ($tags = $element['#value']) {
     // Get the machine names of the vocabularies we will search, keyed by the
     // vocabulary IDs.
-    $field = field_info_field($element['#entity_type'], $element['#field_name']);
+    $field = \Drupal::entityManager()->getFieldStorageDefinitions($element['#entity_type'])[$element['#field_name']];
     $vocabularies = array();
     $allowed_values = $field->getSetting('allowed_values');
     if (!empty($allowed_values)) {
