diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 2b504aa..4ac368a 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -81,6 +81,23 @@ function entity_get_info($entity_type = NULL) {
           }
         }
       }
+
+      // Add custom view modes.
+      $custom_view_modes = config('view_modes')->get();
+      if (!empty($custom_view_modes)) {
+        foreach ($custom_view_modes as $view_mode => $view_mode_info) {
+          $definition = array(
+            'label' => check_plain($view_mode_info['label']),
+            'custom settings' => FALSE,
+          );
+          foreach ($view_mode_info['entity_types'] as $key => $value) {
+            if ($key === $value) {
+              $entity_info[$key]['view modes'][$view_mode] = $definition;
+            }
+          }
+        }
+      }
+
       // Let other modules alter the entity info.
       drupal_alter('entity_info', $entity_info);
       cache()->set("entity_info:$langcode", $entity_info);
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..c827e2b
--- /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(
+      'machine_name' => 'Testing',
+      'label' => 'testing',
+      'entity_types[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',
+      'machine_name' => 'testing',
+      'entity_types[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/edit/testing', $edit, 'Save');
+    $this->assertText('Saved the Testing 2 view mode.', 'Testing label updated');
+
+    // Remove a view mode.
+    $this->drupalPost('admin/config/system/view-modes/delete/testing', 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/view_mode.admin.inc b/core/modules/view_mode/view_mode.admin.inc
new file mode 100644
index 0000000..f8e572c
--- /dev/null
+++ b/core/modules/view_mode/view_mode.admin.inc
@@ -0,0 +1,182 @@
+<?php
+
+/**
+ * @file
+ * Administrative functions for custom view modes.
+ */
+
+/**
+ * Menu callback: list all view modes.
+ */
+function view_mode_list() {
+  $build = $rows = array();
+  $entity_info = entity_get_info();
+  $custom_view_modes = config('view_modes')->get();
+
+  foreach ($custom_view_modes as $view_mode => $view_mode_info) {
+
+    $rows[$view_mode]['label'] = check_plain($view_mode_info['label']);
+    $entity_types = array();
+    foreach ($view_mode_info['entity_types'] as $key => $value) {
+      if ($key === $value) {
+        $entity_types[] = $entity_info[$key]['label'];
+      }
+    }
+    $rows[$view_mode]['custom_settings'] = implode(', ', $entity_types);
+
+    $operations = array();
+    $operations['edit'] = array(
+      'title' => t('Edit'),
+      'href' => "admin/config/system/view-modes/edit/{$view_mode}",
+    );
+    $operations['delete'] = array(
+      'title' => t('Delete'),
+      'href' => "admin/config/system/view-modes/delete/{$view_mode}",
+    );
+    $rows[$view_mode]['operations'] = array(
+      'data' => array(
+        '#theme' => 'links',
+        '#links' => $operations,
+        '#attributes' => array('class' => array('links', 'inline')),
+      ),
+    );
+  }
+
+  if (empty($rows)) {
+    $rows[] = array(array(
+      'data' => t('No custom view modes available.') . ' ' . l(t('Add new view mode.'), "admin/config/system/view-modes/add"),
+      'colspan' => 4,
+    ));
+  }
+
+  $build['view_modes'] = array(
+    '#theme' => 'table',
+    '#header' => array(
+      t('View mode'),
+      t('Entities'),
+      t('Operations'),
+    ),
+    '#rows' => $rows,
+  );
+
+  return $build;
+}
+
+/**
+ * Form builder; add or edit a view mode.
+ */
+function view_mode_edit_form($form, &$form_state, $view_mode = NULL) {
+
+  $form['is_new'] = array(
+    '#type' => 'value',
+    '#value' => empty($view_mode)
+  );
+
+  $form['label'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Label'),
+    '#default_value' => !empty($view_mode['label']) ? $view_mode['label'] : '',
+    '#required' => TRUE,
+  );
+
+  $form['machine_name'] = array(
+    '#type' => 'machine_name',
+    '#machine_name' => array(
+      'source' => array('label'),
+      'exists' => 'view_mode_exists',
+    ),
+    '#default_value' => !empty($view_mode['machine_name']) ? $view_mode['machine_name'] : '',
+    '#disabled' => !empty($view_mode['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['entity_types'] = array(
+    '#required' => TRUE,
+    '#type' => 'checkboxes',
+    '#title' => t('Enable this view mode for the following types'),
+    '#options' => $options,
+    '#default_value' => !empty($view_mode['entity_types']) ? $view_mode['entity_types'] : array(),
+  );
+
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['save'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+  );
+
+  return $form;
+}
+
+/**
+ * Check whether a view mode already exists or not.
+ */
+function view_mode_exists($machine_name, $element, $form_state) {
+  $entity_info = entity_get_info();
+
+  foreach ($entity_info as $entity_type => $info) {
+    foreach (array_keys($info['view modes']) as $view_mode) {
+      if ($view_mode === $machine_name) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ * Submit handler: save a view mode.
+ */
+function view_mode_edit_form_submit($form, &$form_state) {
+  form_state_values_clean($form_state);
+  $view_mode = $form_state['values'];
+  view_mode_save($view_mode);
+
+  drupal_set_message(t('Saved the %view-mode view mode.', array(
+    '%view-mode' => $view_mode['label'],
+  )));
+
+  $form_state['redirect'] = 'admin/config/system/view-modes';
+}
+
+/**
+ * Menu callback: view mode delete confirm form.
+ */
+function view_mode_delete_form($form, $form_state, $view_mode) {
+  $form['#view_mode'] = $view_mode;
+
+  $form['machine_name'] = array(
+    '#type' => 'value',
+    '#value' => $view_mode['machine_name'],
+  );
+
+  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) {
+  view_mode_delete($form_state['values']['machine_name']);
+
+  drupal_set_message(t('Deleted the %view-mode view mode.', array(
+    '%view-mode' => $form['#view_mode']['label'],
+  )));
+  $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..058b210
--- /dev/null
+++ b/core/modules/view_mode/view_mode.module
@@ -0,0 +1,119 @@
+<?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_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' => 'drupal_get_form',
+    'page arguments' => array('view_mode_edit_form'),
+    'access arguments' => array('administer view modes'),
+    'file' => 'view_mode.admin.inc',
+    'type' => MENU_LOCAL_ACTION,
+  );
+  $items['admin/config/system/view-modes/edit/%view_mode'] = array(
+    'title' => 'Edit view mode',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('view_mode_edit_form', 5),
+    'access arguments' => array('administer view modes'),
+    'file' => 'view_mode.admin.inc',
+  );
+  $items['admin/config/system/view-modes/delete/%view_mode'] = array(
+    'title' => 'Delete view mode',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('view_mode_delete_form', 5),
+    '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) {
+
+  $view_mode = config('view_modes')->get($machine_name);
+  if (!empty($view_mode)) {
+    $view_mode['machine_name'] = $machine_name;
+    return $view_mode;
+  }
+
+  return FALSE;
+}
+
+/**
+ * Save a custom entity view mode.
+ */
+function view_mode_save($view_mode) {
+  $is_new = FALSE;
+  $view_mode_name = $view_mode['machine_name'];
+
+  // Determine if we will be inserting a new view mode.
+  if (!isset($view_mode['is_new'])) {
+    $existing = view_mode_load($view_mode_name);
+    $is_new = empty($existing);
+  }
+
+  // Let modules modify the view mode before it is saved.
+  module_invoke_all('view_mode_presave', $view_mode);
+
+  // Save the view mode.
+  $view_mode = array_intersect_key($view_mode, drupal_map_assoc(array('label', 'entity_types')));
+  config('view_modes')->set($view_mode_name, $view_mode)->save();
+
+  // Allow modules to respond after the view mode is saved.
+  if ($is_new) {
+    module_invoke_all('view_mode_insert', $view_mode);
+  }
+  else {
+    module_invoke_all('view_mode_update', $view_mode);
+  }
+
+  // Clear the static entity info cache and rebuild the menu.
+  entity_info_cache_clear();
+  variable_set('menu_rebuild_needed', TRUE);
+}
+
+/**
+ * Delete a custom entity view mode.
+ */
+function view_mode_delete($machine_name) {
+  if ($view_mode = view_mode_load($machine_name)) {
+    module_invoke_all('view_mode_delete', $view_mode);
+
+    $view_modes = config('view_modes')->get();
+    unset($view_modes[$machine_name]);
+    config('view_modes')->setData($view_modes)->save();
+
+    // Clear the static entity info cache and rebuild the menu.
+    entity_info_cache_clear();
+    variable_set('menu_rebuild_needed', TRUE);
+  }
+}
+
