diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/Compare.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/Compare.php
new file mode 100644
index 0000000..41df46d
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/Compare.php
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\filter\Compare.
+ */
+
+namespace Drupal\views\Plugin\views\filter;
+
+use Drupal\Component\Annotation\PluginID;
+
+/**
+ * Defines a filter plugin to compare different fields.
+ *
+ * @ingroup views_filter_handlers
+ *
+ * @PluginID("compare")
+ */
+class Compare extends FilterPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function canExpose() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+
+    $options['left_field'] = array('default' => '');
+    $options['right_field'] = array('default' => '');
+
+    return $options;
+  }
+
+  /**
+   * Provides a list of all operators.
+   *
+   * @return array
+   *   An array of operators.
+   */
+  protected function fieldsOperatorOptions() {
+    return array(
+      '<' => t('Is less than'),
+      '<=' => t('Is less than or equal to'),
+      '=' => t('Is equal to'),
+      '<>' => t('Is not equal to'),
+      '>=' => t('Is greater than or equal to'),
+      '>' => t('Is greater than')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, &$form_state) {
+    parent::buildOptionsForm($form, $form_state);
+
+    $field_options = $this->displayHandler->getFieldLabels();
+    // Filter out the views table as it will not be filterable.
+    foreach (array_keys($field_options) as $id) {
+      if ($this->view->field[$id]->table == 'views') {
+        unset($field_options[$id]);
+      }
+    }
+
+    $form['left_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Left field'),
+      '#default_value' => $this->options['left_field'],
+      '#options' => $field_options,
+      '#weight' => -3,
+    );
+
+    $form['operator'] = array(
+      '#type' => 'select',
+      '#title' => t('Operator'),
+      '#default_value' => $this->options['operator'],
+      '#options' => $this->fieldsOperatorOptions(),
+      '#weight' => -2,
+    );
+
+    $form['right_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Right field'),
+      '#default_value' => $this->options['right_field'],
+      '#options' => $field_options,
+      '#weight' => -1,
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function adminSummary() {
+    return check_plain(
+      $this->options['left_field'] . ' ' .
+      $this->options['operator'] . ' ' .
+      $this->options['right_field']
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * Build extra condition from existing fields (from existing joins).
+   */
+  public function query() {
+    $left = $this->options['left_field'];
+    $right = $this->options['right_field'];
+
+    // Get all existing field handlers.
+    $field_handlers = $this->displayHandler->getHandlers('field');
+
+    // Make sure the selected fields still exist.
+    if (!isset($field_handlers[$left], $field_handlers[$right])) {
+      return;
+    }
+
+    // Get the left table and field.
+    $left_handler = $field_handlers[$left];
+    $left_handler->setRelationship();
+    $left_table_alias = $this->query->ensureTable($left_handler->table, $left_handler->relationship);
+
+    // Get the right table and field.
+    $right_handler = $field_handlers[$right];
+    $right_handler->setRelationship();
+    $right_table_alias = $this->query->ensureTable($right_handler->table, $right_handler->relationship);
+
+    // Build piece of SQL.
+    $snippet = $left_table_alias . '.' . $left_handler->realField . ' ' . $this->options['operator'] . ' ' . $right_table_alias . '.' . $right_handler->realField;
+
+    $this->query->addWhereExpression($this->options['group'], $snippet);
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterCompareTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterCompareTest.php
new file mode 100644
index 0000000..bf98e92
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterCompareTest.php
@@ -0,0 +1,117 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\Handler\FilterCompareTest.
+ */
+
+namespace Drupal\views\Tests\Handler;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+use Drupal\views\Tests\ViewUnitTestBase;
+
+/**
+ * Tests the combine filter handler.
+ *
+ * @see \Drupal\views\Plugin\views\filter\Compare
+ */
+class FilterCompareTest extends ViewUnitTestBase {
+
+  /**
+   * The column map used in the test.
+   *
+   * @var array
+   */
+  protected $columnMap = array(
+    'views_test_data_name' => 'name',
+  );
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = array('test_filter_compare');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Filter: Compare',
+      'description' => 'Tests the compare filter handler.',
+      'group' => 'Views Handlers',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function dataSet() {
+    // Setup age/created so comparing fields can be tested.
+    $data = parent::dataSet();
+
+    $data[0]['age'] = $data[0]['created'];
+    $data[1]['age'] = $data[1]['created'] + 1000;
+    $data[2]['age'] = $data[2]['created'] + 1;
+    $data[3]['age'] = $data[3]['created'] - 1;
+    $data[4]['age'] = $data[4]['created'] - 1000;
+
+    return $data;
+  }
+
+  /**
+   * Tests the compare handler.
+   */
+  public function testCompare() {
+    $view = views_get_view('test_filter_compare');
+
+    // Test the equality operator.
+    $this->executeView($view);
+    $this->assertIdenticalResultset($view, array(array('name' => 'John')), $this->columnMap);
+    $view->destroy();
+
+    // Test the inequality operator.
+    $view->initDisplay();
+    $item = $view->getItem('default', 'filter', 'fields_compare');
+    $item['operator'] = '!=';
+    $view->setItem('default', 'filter', 'fields_compare', $item);
+
+    $this->executeView($view);
+    $expected = array();
+    $expected[] = array('name' => 'George');
+    $expected[] = array('name' => 'Ringo');
+    $expected[] = array('name' => 'Paul');
+    $expected[] = array('name' => 'Meredith');
+
+    $this->assertIdenticalResultset($view, $expected, $this->columnMap);
+    $view->destroy();
+
+    // Test the is greater than operator.
+    $view->initDisplay();
+    $item = $view->getItem('default', 'filter', 'fields_compare');
+    $item['operator'] = '>';
+    $view->setItem('default', 'filter', 'fields_compare', $item);
+
+    $this->executeView($view);
+    $expected = array();
+    $expected[] = array('name' => 'George');
+    $expected[] = array('name' => 'Ringo');
+
+    $this->assertIdenticalResultset($view, $expected, $this->columnMap);
+    $view->destroy();
+
+    // Test the is greater than or equal operator.
+    $view->initDisplay();
+    $item = $view->getItem('default', 'filter', 'fields_compare');
+    $item['operator'] = '>=';
+    $view->setItem('default', 'filter', 'fields_compare', $item);
+
+    $this->executeView($view);
+    $expected = array();
+    $expected[] = array('name' => 'John');
+    $expected[] = array('name' => 'George');
+    $expected[] = array('name' => 'Ringo');
+
+    $this->assertIdenticalResultset($view, $expected, $this->columnMap);
+    $view->destroy();
+  }
+
+}
diff --git a/core/modules/views/tests/views_test_config/test_views/views.view.test_filter_compare.yml b/core/modules/views/tests/views_test_config/test_views/views.view.test_filter_compare.yml
new file mode 100644
index 0000000..8a4f4b7
--- /dev/null
+++ b/core/modules/views/tests/views_test_config/test_views/views.view.test_filter_compare.yml
@@ -0,0 +1,61 @@
+base_table: views_test_data
+core: '8'
+description: ''
+status: '1'
+display:
+  default:
+    display_options:
+      defaults:
+        fields: '0'
+        filters: '0'
+        pager: '0'
+        pager_options: '0'
+        sorts: '0'
+      fields:
+        created:
+          field: created
+          id: created
+          relationship: none
+          table: views_test_data
+          plugin_id: numeric
+        age:
+          field: age
+          id: age
+          relationship: none
+          table: views_test_data
+          plugin_id: numeric
+        name:
+          field: name
+          id: name
+          relationship: none
+          table: views_test_data
+          plugin_id: string
+      pager:
+        options:
+          offset: '0'
+        type: none
+      filters:
+        fields_compare:
+          table: views
+          field: fields_compare
+          id: fields_compare
+          plugin_id: compare
+          left_field: age
+          right_field: created
+          operator: '='
+      pager_options: {  }
+      sorts:
+        id:
+          field: id
+          id: id
+          order: ASC
+          relationship: none
+          table: views_test_data
+          plugin_id: numeric
+    display_plugin: default
+    display_title: Master
+    id: default
+    position: '0'
+label: 'Test view'
+id: test_filter_compare
+tag: ''
diff --git a/core/modules/views/views.views.inc b/core/modules/views/views.views.inc
index 99d23c1..a2d09d8 100644
--- a/core/modules/views/views.views.inc
+++ b/core/modules/views/views.views.inc
@@ -122,5 +122,14 @@ function views_views_data() {
     }
   }
 
+  $data['views']['fields_compare'] = array(
+    'title' => t('Fields comparison'),
+    'help' => t('Compare database fields against each other.'),
+    'filter' => array(
+      'help' => t('Use fields comparison to filter the result of the view.'),
+      'id' => 'compare',
+    )
+  );
+
   return $data;
 }
