diff --git a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
index e673db1..8852f0b 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
@@ -35,17 +35,40 @@ public function getEntityTypeId();
    * @endcode
    *
    * @param $field
-   *   Name of the field being queried. It must contain a field name,
-   *   optionally followed by a column name. The column can be "entity" for
-   *   reference fields and that can be followed similarly by a field name
-   *   and so on. Some examples:
+   *   Name of the field being queried. It must contain a field name, optionally
+   *   followed by a column name. The column can be "entity" for reference
+   *   fields and that can be followed similarly by a field name and so on. Some
+   *   examples:
    *   - nid
    *   - tags.value
    *   - tags
    *   - uid.entity.name
    *   "tags" "is the same as "tags.value" as value is the default column.
    *   If two or more conditions have the same field names they apply to the
-   *   same delta within that field.
+   *   same delta within that field. In order to limit the condition to a
+   *   specific item a numeric delta should be added between the field name and
+   *   the column name.
+   *   @code
+   *   ->condition('tags.5.value', 'news')
+   *   @endcode
+   *   This will require condition to be satisfied on a specific delta of the
+   *   field. The condition above will require the 6th value of the field to
+   *   match the provided value. Further, it's possible to create a condition on
+   *   the delta itself by using '%delta'. For example,
+   *   @code
+   *   ->condition('tags.%delta', 5)
+   *   @endcode
+   *   will find only entities which have at least six tags. Finally, the
+   *   condition on the delta itself accompanied with a condition on the value
+   *   will require the value to appear in the specific delta range. For
+   *   example,
+   *   @code
+   *   ->condition('tags.%delta', 0, '>'))
+   *   ->condition('tags.%delta.value', 'news'))
+   *   @endcode
+   *   will only find the "news" tag if it is not the first value. It should be
+   *   noted that conditions on specific deltas and delta ranges are only
+   *   supported when querying content entities.
    * @param $value
    *   The value for $field. In most cases, this is a scalar and it's treated as
    *   case-insensitive. For more complex operators, it is an array. The meaning
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
index ca25fb9..c8bf59d 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\Query\QueryException;
 use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
+use Drupal\Core\Entity\Sql\TableMappingInterface;
 
 /**
  * Adds tables and fields to the SQL entity query.
@@ -112,11 +113,37 @@ public function addField($field, $type, $langcode) {
 
       // Check whether this field is stored in a dedicated table.
       if ($field_storage && $table_mapping->requiresDedicatedTableStorage($field_storage)) {
+        $delta = NULL;
         // Find the field column.
         $column = $field_storage->getMainPropertyName();
 
         if ($key < $count) {
           $next = $specifiers[$key + 1];
+          // If this is a numeric specifier we're adding a condition on the
+          // specific delta.
+          if (is_numeric($next)) {
+            $delta = $next;
+            $index_prefix .= ".$delta";
+            // Do not process it again.
+            $key++;
+            $next = $specifiers[$key + 1];
+          }
+          // If this specifier is the reserved keyword "%delta" we're adding a
+          // condition on a delta range.
+          elseif ($next == TableMappingInterface::DELTA) {
+            $index_prefix .= TableMappingInterface::DELTA;
+            // Do not process it again.
+            $key++;
+            // If there are more specifiers to work with then continue
+            // processing. If this is the last specifier then use the reserved
+            // keyword as a column name.
+            if ($key < $count) {
+              $next = $specifiers[$key + 1];
+            }
+            else {
+              $column = TableMappingInterface::DELTA;
+            }
+          }
           // Is this a field column?
           $columns = $field_storage->getColumns();
           if (isset($columns[$next]) || in_array($next, $table_mapping->getReservedColumns())) {
@@ -140,7 +167,7 @@ public function addField($field, $type, $langcode) {
             $next_index_prefix = "$relationship_specifier.$column";
           }
         }
-        $table = $this->ensureFieldTable($index_prefix, $field_storage, $type, $langcode, $base_table, $entity_id_field, $field_id_field);
+        $table = $this->ensureFieldTable($index_prefix, $field_storage, $type, $langcode, $base_table, $entity_id_field, $field_id_field, $delta);
         $sql_column = $table_mapping->getFieldColumnName($field_storage, $column);
         $property_definitions = $field_storage->getPropertyDefinitions();
         if (isset($property_definitions[$column])) {
@@ -173,6 +200,27 @@ public function addField($field, $type, $langcode) {
         // next one is a column of this field.
         if ($key < $count) {
           $next = $specifiers[$key + 1];
+          // If this specifier is the reserved keyword "%delta" we're adding a
+          // condition on a delta range.
+          if ($next == TableMappingInterface::DELTA) {
+            $key++;
+            if ($key < $count) {
+              $next = $specifiers[$key + 1];
+            }
+            else {
+              return 0;
+            }
+          }
+          // If this is a numeric specifier we're adding a condition on the
+          // specific delta. Since we know that this is a single value base
+          // field no other value than 0 makes sense.
+          if (is_numeric($next)) {
+            if ($next > 0) {
+              $this->sqlQuery->condition('1 <> 1');
+            }
+            $key++;
+            $next = $specifiers[$key + 1];
+          }
           // Is this a field column?
           $columns = $field_storage->getColumns();
           if (isset($columns[$next]) || in_array($next, $table_mapping->getReservedColumns())) {
@@ -264,7 +312,7 @@ protected function ensureEntityTable($index_prefix, $property, $type, $langcode,
    * @return string
    * @throws \Drupal\Core\Entity\Query\QueryException
    */
-  protected function ensureFieldTable($index_prefix, &$field, $type, $langcode, $base_table, $entity_id_field, $field_id_field) {
+  protected function ensureFieldTable($index_prefix, &$field, $type, $langcode, $base_table, $entity_id_field, $field_id_field, $delta) {
     $field_name = $field->getName();
     if (!isset($this->fieldTables[$index_prefix . $field_name])) {
       $entity_type_id = $this->sqlQuery->getMetaData('entity_type');
@@ -274,12 +322,12 @@ protected function ensureFieldTable($index_prefix, &$field, $type, $langcode, $b
       if ($field->getCardinality() != 1) {
         $this->sqlQuery->addMetaData('simple_query', FALSE);
       }
-      $this->fieldTables[$index_prefix . $field_name] = $this->addJoin($type, $table, "%alias.$field_id_field = $base_table.$entity_id_field", $langcode);
+      $this->fieldTables[$index_prefix . $field_name] = $this->addJoin($type, $table, "%alias.$field_id_field = $base_table.$entity_id_field", $langcode, $delta);
     }
     return $this->fieldTables[$index_prefix . $field_name];
   }
 
-  protected function addJoin($type, $table, $join_condition, $langcode) {
+  protected function addJoin($type, $table, $join_condition, $langcode, $delta = NULL) {
     $arguments = array();
     if ($langcode) {
       $entity_type_id = $this->sqlQuery->getMetaData('entity_type');
@@ -291,6 +339,11 @@ protected function addJoin($type, $table, $join_condition, $langcode) {
       $join_condition .= ' AND %alias.' . $langcode_key . ' = ' . $placeholder;
       $arguments[$placeholder] = $langcode;
     }
+    if (isset($delta)) {
+      $placeholder = ':delta' . $this->sqlQuery->nextPlaceholder();
+      $join_condition .= ' AND %alias.delta = ' . $placeholder;
+      $arguments[$placeholder] = $delta;
+    }
     return $this->sqlQuery->addJoin($type, $table, NULL, $join_condition, $arguments);
   }
 
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/TablesInterface.php b/core/lib/Drupal/Core/Entity/Query/Sql/TablesInterface.php
index 214e130..bd8e0de 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/TablesInterface.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/TablesInterface.php
@@ -11,8 +11,10 @@
    * Adds a field to a database query.
    *
    * @param string $field
-   *   If it contains a dot, then field name dot field column. If it doesn't
-   *   then entity property name.
+   *   If it doesn't contain a dot, then an entity base field name. If it
+   *   contains a dot, then either field name dot field column or field name dot
+   *   delta dot field column. Delta can be a numeric value or a "%delta" for
+   *   any value.
    * @param string $type
    *   Join type, can either be INNER or LEFT.
    * @param string $langcode
diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
index d71949e..aa6fa88 100644
--- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
+++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
@@ -204,7 +204,12 @@ public function getFieldColumnName(FieldStorageDefinitionInterface $storage_defi
       $column_name = count($storage_definition->getColumns()) == 1 ? $field_name : $field_name . '__' . $property_name;
     }
     elseif ($this->requiresDedicatedTableStorage($storage_definition)) {
-      $column_name = !in_array($property_name, $this->getReservedColumns()) ? $field_name . '_' . $property_name : $property_name;
+      if ($property_name == TableMappingInterface::DELTA) {
+        $column_name = 'delta';
+      }
+      else {
+        $column_name = !in_array($property_name, $this->getReservedColumns()) ? $field_name . '_' . $property_name : $property_name;
+      }
     }
     else {
       throw new SqlContentEntityStorageException("Column information not available for the '$field_name' field.");
diff --git a/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php b/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php
index f21c270..3c553bf 100644
--- a/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php
+++ b/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php
@@ -20,6 +20,11 @@
 interface TableMappingInterface {
 
   /**
+   * A property that represents delta used in entity query conditions.
+   */
+  const DELTA = '%delta';
+
+  /**
    * Gets a list of table names for this mapping.
    *
    * @return string[]
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
index 2db824f..ac55a30 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php
@@ -512,6 +512,89 @@ public function testNestedConditionGroups() {
     $this->assertResult(6, 14);
   }
 
+  /**
+   * Test queries with delta conditions.
+   */
+  public function testDelta() {
+    $figures = $this->figures;
+    // Test numeric delta value in field condition.
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("$figures.0.color", 'red')
+      ->sort('id')
+      ->execute();
+    // As unit 0 at delta 0 was the red triangle bit 0 needs to be set.
+    $this->assertResult(1, 3, 5, 7, 9, 11, 13, 15);
+
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("$figures.1.color", 'red')
+      ->sort('id')
+      ->execute();
+    // Delta 1 is not red.
+    $this->assertResult();
+
+    // Test on two different deltas.
+    $query = $this->factory->get('entity_test_mulrev');
+    $or = $query->andConditionGroup()
+      ->condition("$figures.0.color", 'red')
+      ->condition("$figures.1.color", 'blue');
+    $this->queryResults = $query
+      ->condition($or)
+      ->sort('id')
+      ->execute();
+    $this->assertResult(3, 7, 11, 15);
+
+    // Test the delta range condition.
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("$figures.%delta.color", array('blue', 'red'), 'IN')
+      ->condition("$figures.%delta", array(0, 1), 'IN')
+      ->sort('id')
+      ->execute();
+    // Figure delta 0 or 1 can be blue or red, this matches a lot of entities.
+    $this->assertResult(1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15);
+
+    // Test the delta range condition without conditions on the value.
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("$figures.%delta", 1)
+      ->sort('id')
+      ->execute();
+    // Entity needs to have atleast two figures.
+    $this->assertResult(3, 7, 11, 15);
+
+    // Numeric delta on single value base field should return results only if
+    // the first item is being targeted.
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("id.0.value", array(1,3,5), 'IN')
+      ->sort('id')
+      ->execute();
+    $this->assertResult(1, 3, 5);
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("id.1.value", array(1,3,5), 'IN')
+      ->sort('id')
+      ->execute();
+    $this->assertResult();
+
+    // Delta range condition on single value base field should return results
+    // only if just the field value is targeted.
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("id.%delta.value", array(1,3,5), 'IN')
+      ->sort('id')
+      ->execute();
+    $this->assertResult(1, 3, 5);
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("id.%delta.value", array(1,3,5), 'IN')
+      ->condition("id.%delta", 0, '=')
+      ->sort('id')
+      ->execute();
+    $this->assertResult(1, 3, 5);
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition("id.%delta.value", array(1,3,5), 'IN')
+      ->condition("id.%delta", 1, '=')
+      ->sort('id')
+      ->execute();
+    $this->assertResult();
+
+  }
+
   protected function assertResult() {
     $assert = array();
     $expected = func_get_args();
