diff --git a/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php b/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php
index 5768aa9..2a6fb7b 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/ViewsHandlerManager.php
@@ -7,10 +7,12 @@
 
 namespace Drupal\views\Plugin;
 
+use Drupal\Component\Plugin\Exception\PluginException;
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
 use Drupal\views\Plugin\Discovery\ViewsHandlerDiscovery;
+use Drupal\views\ViewsData;
 
 /**
  * Plugin type manager for all views handlers.
@@ -18,6 +20,22 @@
 class ViewsHandlerManager extends PluginManagerBase {
 
   /**
+   * The views data cache.
+   *
+   * @var \Drupal\views\ViewsData
+   */
+  protected $viewsData;
+
+  /**
+   * The handler type.
+   *
+   * @var string
+   *
+   * @see \Drupal\views\ViewExecutable::viewsHandlerTypes().
+   */
+  protected $handlerType;
+
+  /**
    * Constructs a ViewsHandlerManager object.
    *
    * @param string $type
@@ -25,12 +43,80 @@ class ViewsHandlerManager extends PluginManagerBase {
    * @param \Traversable $namespaces
    *   An object that implements \Traversable which contains the root paths
    *   keyed by the corresponding namespace to look for plugin implementations,
+   * @param \Drupal\views\ViewsData $views_data
+   *   The views data cache.
    */
-  public function __construct($type, \Traversable $namespaces) {
+  public function __construct($type, \Traversable $namespaces, ViewsData $views_data) {
     $this->discovery = new ViewsHandlerDiscovery($type, $namespaces);
     $this->discovery = new CacheDecorator($this->discovery, "views:$type", 'views_info');
 
     $this->factory = new DefaultFactory($this->discovery);
+    $this->viewsData = $views_data;
+    $this->handlerType = $type;
+  }
+
+  /**
+   * Fetch a handler from the data cache.
+   *
+   * @param array $item
+   *   An associative array representing the handler to be retrieved:
+   *   - table: The name of the table containing the handler.
+   *   - field: The name of the field the handler represents.
+   *   - optional: (optional) Whether or not this handler is optional. If a
+   *     handler is missing and not optional, a debug message will be displayed.
+   *     Defaults to FALSE.
+   * @param string|null $override
+   *   (optional) Override the actual handler object with this plugin ID. Used for
+   *   aggregation when the handler is redirected to the aggregation handler.
+   *
+   * @return \Drupal\views\Plugin\views\HandlerBase
+   *   An instance of a handler object.
+   */
+  public function getHandler($item, $override = NULL) {
+    $table = $item['table'];
+    $field = $item['field'];
+    $optional = isset($item['optional']) ? $item['optional'] : FALSE;
+    // Get the plugin manager for this type.
+    $data = $this->viewsData->get($table);
+
+    if (isset($data[$field][$this->handlerType])) {
+      $definition = $data[$field][$this->handlerType];
+      foreach (array('group', 'title', 'title short', 'help', 'real field', 'real table') as $key) {
+        if (!isset($definition[$key])) {
+          // First check the field level
+          if (!empty($data[$field][$key])) {
+            $definition[$key] = $data[$field][$key];
+          }
+          // Then if that doesn't work, check the table level
+          elseif (!empty($data['table'][$key])) {
+            $definition[$key] = $data['table'][$key];
+          }
+        }
+      }
+
+      // @todo This is crazy. Find a way to remove the override functionality.
+      $plugin_id = $override ?: $definition['id'];
+      // Try to use the overridden handler.
+      try {
+        return $this->createInstance($plugin_id, $definition);
+      }
+      catch (PluginException $e) {
+        // If that fails, use the original handler.
+        try {
+          return $this->createInstance($definition['id'], $definition);
+        }
+        catch (PluginException $e) {
+          // Deliberately empty, this case is handled generically below.
+        }
+      }
+    }
+
+    if (!$optional) {
+      debug(t("Missing handler: @table @field @type", array('@table' => $table, '@field' => $field, '@type' => $this->handlerType)));
+    }
+
+    // Finally, use the 'broken' handler.
+    return $this->createInstance('broken');
   }
 
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
index 2525071..97bb9bb 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
@@ -872,7 +872,7 @@ public function submitTemporaryForm($form, &$form_state) {
 
     // Create a new handler and unpack the options from the form onto it. We
     // can use that for storage.
-    $handler = views_get_handler($item, $handler_type, $override);
+    $handler = Views::handlerManager($handler_type)->getHandler($item, $override);
     $handler->init($executable, $executable->display_handler, $item);
 
     // Add the incoming options to existing options because items using
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
index 7f6b104..8a6ca65 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
@@ -891,7 +891,7 @@ public function getHandlers($type) {
           $handler_type = $type;
         }
 
-        if ($handler = views_get_handler($info, $handler_type, $override)) {
+        if ($handler = Views::handlerManager($handler_type)->getHandler($info, $override)) {
           // Special override for area types so they know where they come from.
           if ($handler instanceof AreaPluginBase) {
             $handler->areaType = $type;
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php b/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php
index 2376f56..cfedffc 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
+use Drupal\views\Views;
 
 /**
  * Exposed form plugin that provides an exposed form with required input.
@@ -83,7 +84,7 @@ function pre_render($values) {
         'content' => $this->options['text_input_required'],
         'format' => $this->options['text_input_required_format'],
       );
-      $handler = views_get_handler($options, 'area');
+      $handler = Views::handlerManager('area')->getHandler($options);
       $handler->init($this->view, $options);
       $this->displayHandler->handlers['empty'] = array(
         'area' => $handler,
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php
index feb99ef..662b0a1 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php
@@ -71,7 +71,7 @@ public function buildOptionsForm(&$form, &$form_state) {
       $relationship_options = array();
 
       foreach ($relationships as $relationship) {
-        $relationship_handler = views_get_handler($relationship, 'relationship');
+        $relationship_handler = Views::handlerManager('relationship')->getHandler($relationship);
 
         // If this relationship is valid for this type, add it to the list.
         $data = Views::viewsData()->get($relationship['table']);
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php b/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php
index 31452f5..104858c 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Annotation\PluginID;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\ViewExecutable;
+use Drupal\views\Views;
 
 /**
  * Handler for GROUP BY on simple numeric fields.
@@ -25,7 +26,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
     parent::init($view, $display, $options);
 
     // Initialize the original handler.
-    $this->handler = views_get_handler($options, 'sort');
+    $this->handler = Views::handlerManager('sort')->getHandler($options);
     $this->handler->init($view, $display, $options);
   }
 
diff --git a/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php b/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php
index 769efdd..1ab9d4b 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php
@@ -51,7 +51,7 @@ public function testViewsGetHandler() {
         'table' => $this->randomName(),
         'field' => $this->randomName(),
       );
-      $handler = views_get_handler($item, $type);
+      $handler = Views::handlerManager($type)->getHandler($item);
       $this->assertEqual('Drupal\views\Plugin\views\\' . $type . '\Broken', get_class($handler), t('Make sure that a broken handler of type: @type are created', array('@type' => $type)));
     }
 
@@ -66,7 +66,7 @@ public function testViewsGetHandler() {
         );
         foreach ($data as $id => $field_data) {
           if (!in_array($id, array('title', 'help'))) {
-            $handler = views_get_handler($item, $id);
+            $handler = Views::handlerManager($id)->getHandler($item);
             $this->assertInstanceHandler($handler, $table, $field, $id);
           }
         }
@@ -78,7 +78,7 @@ public function testViewsGetHandler() {
       'table' => 'views_test_data',
       'field' => 'job',
     );
-    $handler = views_get_handler($item, 'filter', 'standard');
+    $handler = Views::handlerManager('filter')->getHandler($item, 'standard');
     $this->assertTrue($handler instanceof Standard);
 
     // Test non-existent tables/fields.
@@ -87,7 +87,7 @@ public function testViewsGetHandler() {
       'table' => 'views_test_data',
       'field' => 'field_invalid',
     );
-    views_get_handler($item, 'field');
+    Views::handlerManager('field')->getHandler($item);
     $this->assertTrue(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'views_test_data', '@field' => 'field_invalid', '@type' => 'field'))) !== FALSE, 'An invalid field name throws a debug message.');
     unset($this->lastErrorMessage);
 
@@ -95,7 +95,7 @@ public function testViewsGetHandler() {
       'table' => 'table_invalid',
       'field' => 'id',
     );
-    views_get_handler($item, 'filter');
+    Views::handlerManager('filter')->getHandler($item);
     $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.');
     unset($this->lastErrorMessage);
 
@@ -104,7 +104,7 @@ public function testViewsGetHandler() {
       'field' => 'id',
       'optional' => FALSE,
     );
-    views_get_handler($item, 'filter');
+    Views::handlerManager('filter')->getHandler($item);
     $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.');
     unset($this->lastErrorMessage);
 
@@ -113,8 +113,7 @@ public function testViewsGetHandler() {
       'field' => 'id',
       'optional' => TRUE,
     );
-
-    views_get_handler($item, 'filter');
+    Views::handlerManager('filter')->getHandler($item);
     $this->assertFalse($this->lastErrorMessage, "An optional handler does not throw a debug message.");
     unset($this->lastErrorMessage);
 
diff --git a/core/modules/views/lib/Drupal/views/Views.php b/core/modules/views/lib/Drupal/views/Views.php
index 9af207c..3c45ab3 100644
--- a/core/modules/views/lib/Drupal/views/Views.php
+++ b/core/modules/views/lib/Drupal/views/Views.php
@@ -56,4 +56,13 @@ public static function pluginManager($type) {
     return Drupal::service('plugin.manager.views.' . $type);
   }
 
+  /**
+   * Returns the plugin manager for a certain views handler type.
+   *
+   * @return \Drupal\views\Plugin\ViewsHandlerManager
+   */
+  public static function handlerManager($type) {
+    return Drupal::service('plugin.manager.views.' . $type);
+  }
+
 }
diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml
index 1629da5..93abaab 100644
--- a/core/modules/views/views.services.yml
+++ b/core/modules/views/views.services.yml
@@ -4,10 +4,10 @@ services:
     arguments: [access, '@container.namespaces']
   plugin.manager.views.area:
     class: Drupal\views\Plugin\ViewsHandlerManager
-    arguments: [area, '@container.namespaces']
+    arguments: [area, '@container.namespaces', '@views.views_data']
   plugin.manager.views.argument:
     class: Drupal\views\Plugin\ViewsHandlerManager
-    arguments: [argument, '@container.namespaces']
+    arguments: [argument, '@container.namespaces', '@views.views_data']
   plugin.manager.views.argument_default:
     class: Drupal\views\Plugin\ViewsPluginManager
     arguments: [argument_default, '@container.namespaces']
@@ -28,13 +28,13 @@ services:
     arguments: [exposed_form, '@container.namespaces']
   plugin.manager.views.field:
     class: Drupal\views\Plugin\ViewsHandlerManager
-    arguments: [field, '@container.namespaces']
+    arguments: [field, '@container.namespaces', '@views.views_data']
   plugin.manager.views.filter:
     class: Drupal\views\Plugin\ViewsHandlerManager
-    arguments: [filter, '@container.namespaces']
+    arguments: [filter, '@container.namespaces', '@views.views_data']
   plugin.manager.views.join:
     class: Drupal\views\Plugin\ViewsHandlerManager
-    arguments: [join, '@container.namespaces']
+    arguments: [join, '@container.namespaces', '@views.views_data']
   plugin.manager.views.pager:
     class: Drupal\views\Plugin\ViewsPluginManager
     arguments: [pager, '@container.namespaces']
@@ -43,13 +43,13 @@ services:
     arguments: [query, '@container.namespaces']
   plugin.manager.views.relationship:
     class: Drupal\views\Plugin\ViewsHandlerManager
-    arguments: [relationship, '@container.namespaces']
+    arguments: [relationship, '@container.namespaces', '@views.views_data']
   plugin.manager.views.row:
     class: Drupal\views\Plugin\ViewsPluginManager
     arguments: [row, '@container.namespaces']
   plugin.manager.views.sort:
     class: Drupal\views\Plugin\ViewsHandlerManager
-    arguments: [sort, '@container.namespaces']
+    arguments: [sort, '@container.namespaces', '@views.views_data']
   plugin.manager.views.style:
     class: Drupal\views\Plugin\ViewsPluginManager
     arguments: [style, '@container.namespaces']
