diff --git a/core/lib/Drupal/Core/Entity/Query/QueryBase.php b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
index 38deabd..d84a266 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryBase.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
@@ -109,6 +109,13 @@
   protected $allRevisions = FALSE;
 
   /**
+   * Flag indicating whether to query the latest revision.
+   *
+   * @var bool
+   */
+  protected $latestRevision = FALSE;
+
+  /**
    * The query pager data.
    *
    * @var array
@@ -252,6 +259,16 @@ public function accessCheck($access_check = TRUE) {
    */
   public function currentRevision() {
     $this->allRevisions = FALSE;
+    $this->latestRevision = FALSE;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function latestRevision() {
+    $this->allRevisions = TRUE;
+    $this->latestRevision = TRUE;
     return $this;
   }
 
@@ -260,6 +277,7 @@ public function currentRevision() {
    */
   public function allRevisions() {
     $this->allRevisions = TRUE;
+    $this->latestRevision = FALSE;
     return $this;
   }
 
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
index df37520..63102ef 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
@@ -255,6 +255,17 @@ public function orConditionGroup();
   public function currentRevision();
 
   /**
+   * Queries the latest revision.
+   *
+   * The latest revision is the most recent revision of an entity. This will be
+   * either the default revision, or a draft revision if one exists and it is
+   * newer than the default.
+   *
+   * @return $this
+   */
+  public function latestRevision();
+
+  /**
    * Queries all the revisions.
    *
    * @return $this
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
index cd245ef..50b81bb 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
@@ -119,6 +119,14 @@ protected function prepare() {
       // entity id.
       $this->sqlFields["base_table.$id_field"] = ['base_table', $id_field];
     }
+
+    // Add a self-join to the base revision table if we're querying only the
+    // latest revisions.
+    if ($this->latestRevision && $revision_field) {
+      $this->sqlQuery->leftJoin($base_table, 'base_table_2', "base_table.$id_field = base_table_2.$id_field AND base_table.$revision_field < base_table_2.$revision_field");
+      $this->sqlQuery->isNull("base_table_2.$id_field");
+    }
+
     if ($this->accessCheck) {
       $this->sqlQuery->addTag($this->entityTypeId . '_access');
     }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
index ec33f67..ebb3072 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
@@ -318,6 +318,16 @@ public function testEntityQuery() {
     // Now we get everything.
     $assert = [4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15'];
     $this->assertIdentical($results, $assert);
+
+    // Check that a query on the latest revisions without any condition returns
+    // the correct results.
+    $results = $this->factory->get('entity_test_mulrev')
+      ->latestRevision()
+      ->sort('id')
+      ->sort('revision_id')
+      ->execute();
+    $expected = [1 => '1', 2 => '2', 3 => '3', 16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15'];
+    $this->assertSame($expected, $results);
   }
 
   /**
@@ -936,6 +946,54 @@ public function testPendingRevisions() {
       ->allRevisions()
       ->execute();
     $this->assertEqual($result, [16 => '14']);
+
+    // Add another pending revision on the same entity and repeat the checks.
+    $entity->setNewRevision(TRUE);
+    $entity->isDefaultRevision(FALSE);
+    $entity->{$this->figures}->setValue([
+      'color' => 'red',
+      'shape' => 'square'
+    ]);
+    $entity->save();
+
+    // A non-revisioned entity query should still return entity 14.
+    $result = $this->factory->get('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->execute();
+    $this->assertCount(1, $result);
+    $this->assertSame([14 => '14'], $result);
+
+    // Now check an entity query on the latest revision.
+    $result = $this->factory->get('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->latestRevision()
+      ->execute();
+    $this->assertCount(1, $result);
+    $this->assertSame([17 => '14'], $result);
+
+    // Verify that field conditions on the default and pending revision still
+    // work as expected.
+    $result = $this->factory->get('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->condition("$this->figures.color", $current_values[0]['color'])
+      ->execute();
+    $this->assertSame([14 => '14'], $result);
+
+    // Now there are two revisions with same value for the figure color.
+    $result = $this->factory->get('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->condition("$this->figures.color", 'red')
+      ->allRevisions()
+      ->execute();
+    $this->assertSame([16 => '14', 17 => '14'], $result);
+
+    // Check that querying for the latest revision returns the correct one.
+    $result = $this->factory->get('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->condition("$this->figures.color", 'red')
+      ->latestRevision()
+      ->execute();
+    $this->assertSame([17 => '14'], $result);
   }
 
   /**
