diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 75c3386..639c53d 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -82,6 +82,20 @@ function entity_get_info($entity_type = NULL) {
           }
         }
       }
+
+      // Add view modes.
+      $view_modes = drupal_container()->get('config.storage')->listAll('view_mode.');
+      foreach ($view_modes as $config_name) {
+        $view_mode = config($config_name)->get();
+        $definition = array(
+          'label' => check_plain($view_mode['label']),
+          'custom settings' => FALSE,
+        );
+        foreach (array_filter($view_mode['entityTypes']) as $key => $value) {
+          $entity_info[$key]['view modes'][$view_mode['name']] = $definition;
+        }
+      }
+
       // Let other modules alter the entity info.
       drupal_alter('entity_info', $entity_info);
       cache()->set("entity_info:$langcode", $entity_info, CacheBackendInterface::CACHE_PERMANENT, array('entity_info' => TRUE));
diff --git a/core/lib/Drupal/Core/Entity/EntityViewMode.php b/core/lib/Drupal/Core/Entity/EntityViewMode.php
new file mode 100644
index 0000000..dd49744
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EntityViewMode.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Entity\EntityViewMode.
+ */
+
+namespace Drupal\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+
+/**
+ * @todo.
+ */
+class EntityViewMode extends ConfigEntityBase {
+
+  /**
+   * @todo.
+   *
+   * @var string
+   */
+  public $name;
+
+  /**
+   * @todo.
+   *
+   * @var string
+   */
+  public $label;
+
+  /**
+   * @todo.
+   *
+   * @var array
+   */
+  public $entityTypes = array();
+
+  public function id() {
+    return $this->name;
+  }
+
+  public function uri() {
+    return array(
+      'path' => 'admin/config/system/view-modes/' . $this->id(),
+      'options' => array(),
+    );
+  }
+
+  public function getUsedEntityTypes() {
+    return drupal_map_assoc(array_filter($this->entityTypes));
+  }
+
+}
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index d1c314d..bb89fc4 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1079,6 +1079,28 @@ function system_menu() {
 }
 
 /**
+ * Implements hook_entity_info().
+ */
+function system_entity_info() {
+  $return = array(
+    'view_mode' => array(
+      'label' => t('View mode'),
+      'entity class' => 'Drupal\Core\Entity\EntityViewMode',
+      'controller class' => 'Drupal\Core\Config\Entity\ConfigStorageController',
+      'config prefix' => 'view_mode',
+      'fieldable' => FALSE,
+      'entity keys' => array(
+        'id' => 'name',
+        'label' => 'label',
+        'uuid' => 'uuid',
+      ),
+    ),
+  );
+
+  return $return;
+}
+
+/**
  * Page callback; Execute cron tasks.
  *
  * @see system_cron_access().
diff --git a/core/modules/view_mode/lib/Drupal/view_mode/Tests/ViewModeTest.php b/core/modules/view_mode/lib/Drupal/view_mode/Tests/ViewModeTest.php
new file mode 100644
index 0000000..141edb0
--- /dev/null
+++ b/core/modules/view_mode/lib/Drupal/view_mode/Tests/ViewModeTest.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\view_mode\Tests\ViewModeTest.
+ */
+
+namespace Drupal\view_mode\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Test managing of view modes.
+ */
+class ViewModeTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('field_ui', 'view_mode');
+
+  protected $profile = 'standard';
+
+
+  /**
+   * Implements getInfo().
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('View modes'),
+      'description' => t('Tests for managing custom view modes.'),
+      'group' => t('View mode'),
+    );
+  }
+
+  /**
+   * Implements setUp().
+   */
+  function setUp() {
+    parent::setUp();
+
+    $this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer users', 'administer view modes', 'access administration pages'));
+    $this->drupalLogin($this->admin_user);
+  }
+
+  /**
+   * Create a view mode.
+   *
+   * @param $edit
+   *   An optional array of view mode properties.
+   */
+  function createViewMode($edit = array()) {
+
+    $edit += array(
+      'name' => 'Testing',
+      'label' => 'testing',
+      'entityTypes[node]' => '1'
+    );
+
+    $this->drupalPost('admin/config/system/view-modes/add', $edit, 'Save');
+    $this->assertText(format_string('Saved the !name view mode.', array('!name' => $edit['label'])));
+  }
+
+  /**
+   * Test managing view modes.
+   */
+  function testManageViewModes() {
+
+    $edit = array(
+      'label' => 'Testing',
+      'name' => 'testing',
+      'entityTypes[node]' => '1'
+    );
+
+    $this->createViewMode($edit);
+
+    // Create the same and assert it already exists.
+    $this->drupalPost('admin/config/system/view-modes/add', $edit, 'Save');
+    $this->assertText('The machine-readable name is already in use. It must be unique.', 'View mode testing already exists.');
+
+    // Assert it's found on the Field UI for article.
+    $this->drupalGet('admin/structure/types/manage/article/display');
+    $this->assertRaw('view_modes_custom[testing]', 'Testing view mode found on node article.');
+
+    // Assert it's not found on the Field UI for user.
+    $this->drupalGet('admin/config/people/accounts/display');
+    $this->assertNoRaw('view_modes_custom[testing]', 'Testing view mode not found on user.');
+
+    // Update testing label
+    $edit = array(
+      'label' => 'Testing 2',
+    );
+    $this->drupalPost('admin/config/system/view-modes/testing/edit', $edit, 'Save');
+    $this->assertText('Saved the Testing 2 view mode.', 'Testing label updated');
+
+    // Remove a view mode.
+    $this->drupalPost('admin/config/system/view-modes/testing/delete', array(), 'Delete');
+    $this->assertText('Deleted the Testing 2 view mode', 'Deleted the Testing view mode');
+
+    // Assert the view mode is gone at the manage display screen.
+    $this->drupalGet('admin/structure/types/manage/article/display');
+    $this->assertNoRaw('view_modes_custom[testing]', 'Testing view mode not found on node article.');
+  }
+}
diff --git a/core/modules/view_mode/lib/Drupal/view_mode/ViewModeFormController.php b/core/modules/view_mode/lib/Drupal/view_mode/ViewModeFormController.php
new file mode 100644
index 0000000..4c14a70
--- /dev/null
+++ b/core/modules/view_mode/lib/Drupal/view_mode/ViewModeFormController.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\view_mode\ViewModeFormController.
+ */
+
+namespace Drupal\view_mode;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityFormController;
+
+/**
+ * Form controller for the view mode forms.
+ */
+class ViewModeFormController extends EntityFormController {
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::form().
+   */
+  public function form(array $form, array &$form_state, EntityInterface $view_mode) {
+    $label = $view_mode->label();
+    $form['is_new'] = array(
+      '#type' => 'value',
+      '#value' => $view_mode->isNew(),
+    );
+
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Label'),
+      '#default_value' => $label,
+      '#required' => TRUE,
+    );
+
+    $form['name'] = array(
+      '#type' => 'machine_name',
+      '#machine_name' => array(
+        'source' => array('label'),
+        'exists' => 'view_mode_load',
+      ),
+      '#default_value' => $view_mode->id(),
+      '#disabled' => !empty($label),
+    );
+
+    $options = array();
+    $entity_info = entity_get_info();
+    foreach ($entity_info as $entity_type => $info) {
+      if (!empty($info['fieldable'])) {
+        $options[$entity_type] = $info['label'];
+      }
+    }
+
+    $form['entityTypes'] = array(
+      '#required' => TRUE,
+      '#type' => 'checkboxes',
+      '#title' => t('Enable this view mode for the following types'),
+      '#options' => $options,
+      '#default_value' => $view_mode->getUsedEntityTypes(),
+    );
+
+    return $form;
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::save().
+   */
+  public function save(array $form, array &$form_state) {
+    $view_mode = $this->getEntity($form_state);
+    $view_mode->save();
+    drupal_set_message(t('Saved the %view-mode view mode.', array(
+      '%view-mode' => $view_mode->label(),
+    )));
+
+    $form_state['redirect'] = 'admin/config/system/view-modes';
+
+    // Clear the static entity info cache and rebuild the menu.
+    entity_info_cache_clear();
+    state()->set('menu_rebuild_needed', TRUE);
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::delete().
+   */
+  public function delete(array $form, array &$form_state) {
+    $destination = array();
+    if (isset($_GET['destination'])) {
+      $destination = drupal_get_destination();
+      unset($_GET['destination']);
+    }
+    $view_mode = $this->getEntity($form_state);
+    $form_state['redirect'] = array('admin/config/system/view-modes/' . $view_mode->id() . '/delete', array('query' => $destination));
+
+    // Clear the static entity info cache and rebuild the menu.
+    entity_info_cache_clear();
+    state()->set('menu_rebuild_needed', TRUE);
+  }
+
+}
diff --git a/core/modules/view_mode/view_mode.admin.inc b/core/modules/view_mode/view_mode.admin.inc
new file mode 100644
index 0000000..8b55c90
--- /dev/null
+++ b/core/modules/view_mode/view_mode.admin.inc
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Administrative functions for custom view modes.
+ */
+
+/**
+ * Menu callback: list all view modes.
+ */
+function view_mode_list() {
+  return entity_list_controller('view_mode')->render();
+}
+
+/**
+ * Menu callback: view mode edit form.
+ */
+function view_mode_add() {
+  $view_mode = entity_create('view_mode', array());
+  return entity_get_form($view_mode);
+}
+
+/**
+ * Menu callback: view mode delete confirm form.
+ */
+function view_mode_delete_form($form, $form_state, $view_mode) {
+  $form['#view_mode'] = $view_mode;
+
+  $form['name'] = array(
+    '#type' => 'value',
+    '#value' => $view_mode->id(),
+  );
+
+  return confirm_form(
+    $form,
+    t('Are you sure you want to delete the %view-mode view mode?', array(
+      '%view-mode' => $view_mode->label(),
+    )),
+    'admin/config/system/view-modes',
+    t('Deleting a view mode will cause any output still requesting to use that view mode to use the default display settings.'),
+    t('Delete'),
+    t('Cancel')
+  );
+}
+
+/**
+ * Submit handler: delete a view mode.
+ */
+function view_mode_delete_form_submit($form, &$form_state) {
+  drupal_set_message(t('Deleted the %view-mode view mode.', array(
+    '%view-mode' => $form['#view_mode']->label(),
+  )));
+  $form['#view_mode']->delete();
+  $form_state['redirect'] = 'admin/config/system/view-modes';
+}
diff --git a/core/modules/view_mode/view_mode.info b/core/modules/view_mode/view_mode.info
new file mode 100644
index 0000000..56157b8
--- /dev/null
+++ b/core/modules/view_mode/view_mode.info
@@ -0,0 +1,7 @@
+name = View modes
+description = Allows administrators to define custom view modes for entities via the administration user interface.
+package = Core
+version = VERSION
+core = 8.x
+recommends[] = field_ui
+configure = admin/config/system/view-modes
diff --git a/core/modules/view_mode/view_mode.module b/core/modules/view_mode/view_mode.module
new file mode 100644
index 0000000..a863aa6
--- /dev/null
+++ b/core/modules/view_mode/view_mode.module
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Manage custom view modes.
+ */
+
+/**
+ * Implements hook_permission().
+ */
+function view_mode_permission() {
+  return array(
+    'administer view modes' => array(
+      'title' => t('Add, edit and delete custom view modes.'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_entity_info_alter().
+ */
+function view_mode_entity_info_alter(&$entity_info) {
+  $entity_info['view_mode']['list controller class'] = 'Drupal\Core\Config\Entity\ConfigEntityListController';
+  $entity_info['view_mode']['form controller class'] = array(
+    'default' => 'Drupal\view_mode\ViewModeFormController',
+  );
+}
+
+/**
+ * Implements hook_menu().
+ */
+function view_mode_menu() {
+  $items['admin/config/system/view-modes'] = array(
+    'title' => 'View modes',
+    'description' => 'Manage custom view modes.',
+    'page callback' => 'view_mode_list',
+    'access arguments' => array('administer view modes'),
+    'file' => 'view_mode.admin.inc',
+  );
+  $items['admin/config/system/view-modes/add'] = array(
+    'title' => 'Add view mode',
+    'page callback' => 'view_mode_add',
+    'access arguments' => array('administer view modes'),
+    'file' => 'view_mode.admin.inc',
+    'type' => MENU_LOCAL_ACTION,
+  );
+  $items['admin/config/system/view-modes/%view_mode/edit'] = array(
+    'title' => 'Edit view mode',
+    'page callback' => 'entity_get_form',
+    'page arguments' => array(4),
+    'access arguments' => array('administer view modes'),
+  );
+  $items['admin/config/system/view-modes/%view_mode/delete'] = array(
+    'title' => 'Delete view mode',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('view_mode_delete_form', 4),
+    'access arguments' => array('administer view modes'),
+    'file' => 'view_mode.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
+ * Load a custom view mode by machine name.
+ */
+function view_mode_load($machine_name) {
+  return entity_load('view_mode', $machine_name);
+}
+
+/**
+ * Implements hook_view_mode_delete().
+ */
+function view_mode_view_mode_delete($entity) {
+  entity_info_cache_clear();
+}
