diff --git includes/entity.inc includes/entity.inc
index 1884612..a675a7f 100644
--- includes/entity.inc
+++ includes/entity.inc
@@ -462,6 +462,24 @@ class EntityFieldQuery {
   public $range = array();
 
   /**
+   * The query pager.
+   *
+   * @var array
+   *
+   * @see EntityFieldQuery::pager()
+   */
+  public $pager = array();
+
+  /**
+   * The TableSort header.
+   *
+   * @var array
+   *
+   * @see EntityFieldQuery::tableSort()
+   */
+  public $tableSort = array();
+
+  /**
    * Query behavior for deleted data.
    *
    * TRUE to return only deleted data, FALSE to return only non-deleted data,
@@ -790,6 +808,61 @@ class EntityFieldQuery {
     );
     return $this;
   }
+  
+  /**
+   * Enable a pager for the query.
+   *
+   * @param $limit
+   *   An integer specifying the number of elements per page.  If passed a false
+   *   value (FALSE, 0, NULL), the pager is disabled.
+   * @param $element
+   *   An optional integer to distinguish between multiple pagers on one page.
+   *
+   * @return EntityFieldQuery
+   *   The called object.
+   */
+  public function pager($limit = 10, $element = NULL) {
+    $this->pager = array(
+      'limit' => $limit,
+      'element' => $element,
+    );
+    return $this;
+  }
+  
+  /**
+   * Enable sortable tables for this query.
+   *
+   * @param $header
+   *   An EFQ Header array.
+   *   Transformed into an SQL header array for orderByHeader on query execution.
+   *
+   * @return EntityFieldQuery
+   *   The called object.
+   */
+  public function tableSort($header) {
+    // If we have any ordering by fields, we need to populate $this->fields
+    // and save $field and $index for later use.
+    foreach ($header as $key => $options) {
+      if (!is_array($options)) {
+        continue;
+      }
+
+      if ($options['type'] == 'field') {
+        $field = field_info_field($options['specifier']['field']);
+        $index = count($this->fields);
+        $this->fields[$index] = $field;
+        $options['specifier']['field'] = $field;
+        $options['specifier']['index'] = $index;
+        $header[$key] = $options;
+      }
+    }
+    $this->order[] = array(
+      'type' => 'tablesort',
+      'specifier' => $header,
+    );
+    $this->tableSort = $header;
+    return $this;
+  }
 
   /**
    * Filters on the data being deleted.
@@ -1011,16 +1084,28 @@ class EntityFieldQuery {
     }
     
     // Order the query.
+    // For that to work, all specifiers need to be mapped to their sql fields.
+    // In case of a tablesort, the EFQ header needs to be transformed into a
+    // format that TableSort::orderByHeader() can understand.
     foreach ($this->order as $order) {
-      if ($order['type'] == 'entity') {
-        $key = $order['specifier'];
-        if (!isset($id_map[$key])) {
-          throw new EntityFieldQueryException(t('Do not know how to order on @key for @entity_type', array('@key' => $key, '@entity_type' => $entity_type)));
+      if ($order['type'] == 'tablesort') {
+        $header = $order['specifier'];
+        foreach ($header as $key => $options) {
+          if (!is_array($options)) {
+            continue;
+          }
+          
+          $header[$key]['field'] = $this->propertyMap($options, $entity_type, $id_map);
+          unset($header[$key]['type']);
+          unset($header[$key]['specifier']);
         }
-        $select_query->orderBy($id_map[$key], $order['direction']);
+        $this->tableSort = $header;
+        $select_query = $select_query->extend('TableSort');
+        $select_query->orderByHeader($header);
       }
-      elseif ($order['type'] == 'property') {
-        $select_query->orderBy("$base_table." . $order['specifier'], $order['direction']);
+      else {
+        $field = $this->propertyMap($order, $entity_type, $id_map);
+        $select_query->orderBy($field, $order['direction']);
       }
     }
     
@@ -1030,7 +1115,7 @@ class EntityFieldQuery {
   /**
    * Finishes the query.
    *
-   * Adds tags, metaData, range and returns the requested list or count.
+   * Adds tags, metaData, range, pager and returns the requested list or count.
    *
    * @param SelectQuery $select_query
    *   A SelectQuery which has entity_type, entity_id, revision_id and bundle
@@ -1055,6 +1140,11 @@ class EntityFieldQuery {
     if ($this->count) {
       return $select_query->countQuery()->execute()->fetchField();
     }
+    if (count($this->pager)) {
+      $select_query = $select_query->extend('PagerDefault');
+      $select_query->limit($this->pager['limit']);
+      $select_query->element($this->pager['element']);
+    }
     $return = array();
     foreach ($select_query->execute() as $partial_entity) {
       $entity = entity_create_stub_entity($partial_entity->entity_type, array($partial_entity->entity_id, $partial_entity->revision_id, $partial_entity->bundle));
@@ -1065,6 +1155,37 @@ class EntityFieldQuery {
   }
 
   /**
+   * Maps a given element to a field in the database.
+   * Used for ordering and tablesort.
+   *
+   * @param $element
+   *   The passed element that we map to a field based on it's type.
+   * @param $entity_type
+   *   Entity type.
+   * @param $id_map
+   *   An array of entity field mappings.
+   *
+   * @return The mapped sql field.
+   */
+  function propertyMap($element, $entity_type, $id_map) {
+    $sql_field = '';
+
+    if ($element['type'] == 'entity') {
+      $key = $element['specifier'];
+      if (!isset($id_map[$key])) {
+        throw new EntityFieldQueryException(t('Do not know how to order on @key for @entity_type', array('@key' => $key, '@entity_type' => $entity_type)));
+      }
+
+      $sql_field = $id_map[$key];
+    }
+    elseif ($element['type'] == 'property') {
+      $sql_field = $element['specifier'];
+    }
+
+    return $sql_field;
+  }
+
+  /**
    * Adds a condition to an already built SelectQuery (internal function).
    *
    * This is a helper for hook_entity_query() and hook_field_storage_query().
diff --git modules/field/modules/field_sql_storage/field_sql_storage.module modules/field/modules/field_sql_storage/field_sql_storage.module
index ea52707..eb5d47b 100644
--- modules/field/modules/field_sql_storage/field_sql_storage.module
+++ modules/field/modules/field_sql_storage/field_sql_storage.module
@@ -548,8 +548,16 @@ function field_sql_storage_field_storage_query(EntityFieldQuery $query) {
     if ($order['type'] == 'property') {
       $has_property_order = TRUE;
     }
+    elseif ($order['type'] == 'tablesort') {
+      foreach ($order['specifier'] as $options) {
+        if ($options['type'] == 'property') {
+          $has_property_order = TRUE;
+        }
+      }
+    }
   }
   
+  $entity_base_table = '';
   if ($query->propertyConditions || $has_property_order) {
     if (empty($query->entityConditions['entity_type']['value'])) {
       throw new EntityFieldQueryException('Property conditions and orders must have an entity type defined.');
@@ -567,24 +575,31 @@ function field_sql_storage_field_storage_query(EntityFieldQuery $query) {
   }
   
   // Order the query.
+  // For that to work, all specifiers need to be mapped to their sql fields.
+  // In case of a tablesort, the EFQ header needs to be transformed into a
+  // format that TableSort::orderByHeader() can understand.
   foreach ($query->order as $order) {
-    if ($order['type'] == 'entity') {
-      $key = $order['specifier'];
-      $sql_field = $key == 'entity_type' ? 'fcet.type' : "$field_base_table.$key";
-      $select_query->orderBy($sql_field, $order['direction']);
-    }
-    elseif ($order['type'] == 'field') {
-      $specifier = $order['specifier'];
-      $field = $specifier['field'];
-      $table_alias = $table_aliases[$specifier['index']];
-      $sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $specifier['column']);
-      $select_query->orderBy($sql_field, $order['direction']);
+    if ($order['type'] == 'tablesort') {
+      $header = $order['specifier'];
+      foreach ($order['specifier'] as $key => $options) {
+        if (!is_array($options)) {
+          continue;
+        }
+
+        $header[$key]['field'] = _field_sql_storage_map($options, $entity_base_table, $field_base_table, $table_aliases);
+        unset($header[$key]['type']);
+        unset($header[$key]['specifier']);
+      }
+      $query->tableSort = $header;
+      $select_query = $select_query->extend('TableSort');
+      $select_query->orderByHeader($header);
     }
-    elseif ($order['type'] == 'property') {
-      $select_query->orderBy("$entity_base_table." . $order['specifier'], $order['direction']);
+    else {
+      $field = _field_sql_storage_map($order, $entity_base_table, $field_base_table, $table_aliases);
+      $select_query->orderBy($field, $order['direction']);
     }
   }
-  
+
   return $query->finishQuery($select_query, $id_key);
 }
 
@@ -612,6 +627,41 @@ function _field_sql_storage_query_join_entity(SelectQuery $select_query, $entity
 }
 
 /**
+ * Maps a given element to a field in the database.
+ * Used for ordering and tablesort.
+ *
+ * @param $element
+ *   The passed element that we map to a field based on it's type.
+ * @param $entity_base_table
+ *   Entity base table.
+ * @param $field_base_table
+ *   Field base table.
+ * @param $table_aliases
+ *   An array of joined table aliases.
+ *
+ * @return The mapped sql field.
+ */
+function _field_sql_storage_map($element, $entity_base_table, $field_base_table, $table_aliases) {
+  $sql_field = '';
+
+  if ($element['type'] == 'field') {
+    $field = $element['specifier']['field'];
+    $index = $element['specifier']['index'];
+    $table_alias = $table_aliases[$index];
+    $sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $element['specifier']['column']);
+  }
+  elseif ($element['type'] == 'entity') {
+    $specifier = $element['specifier'];
+    $sql_field = $specifier == 'entity_type' ? 'fcet.type' : "$field_base_table.$specifier";
+  }
+  elseif ($element['type'] == 'property') {
+    $sql_field = "$entity_base_table." . $element['specifier'];
+  }
+
+  return $sql_field;
+}
+
+/**
  * Implements hook_field_storage_delete_revision().
  *
  * This function actually deletes the data from the database.
diff --git modules/simpletest/tests/entity_query.test modules/simpletest/tests/entity_query.test
index 32edf38..e7247b4 100644
--- modules/simpletest/tests/entity_query.test
+++ modules/simpletest/tests/entity_query.test
@@ -1090,6 +1090,238 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
     }
     $this->assertTrue($pass, t('Cannot query across field storage engines.'));
   }
+  
+  /**
+   * Tests the pager integration of EntityFieldQuery.
+   */
+  function testEntityFieldQueryPager() {
+    // Test pager in propertyQuery
+    $_GET['page'] = "0,1";
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->propertyOrderBy('ftid', 'ASC')
+      ->pager(3, 0);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+    ), t('Test pager integration in propertyQuery: page 1.'), TRUE);
+    
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->propertyOrderBy('ftid', 'ASC')
+      ->pager(3, 1);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
+    ), t('Test pager integration in propertyQuery: page 2.'), TRUE);
+    
+    // Test pager in field storage
+    $_GET['page'] = "0,1";
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->propertyOrderBy('ftid', 'ASC')
+      ->pager(2, 0);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+    ), t('Test pager integration in field storage: page 1.'), TRUE);
+    
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->propertyOrderBy('ftid', 'ASC')
+      ->pager(2, 1);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+    ), t('Test pager integration in field storage: page 2.'), TRUE);
+    
+    unset($_GET['page']);
+  }
+
+  /**
+   * Tests the TableSort integration of EntityFieldQuery.
+   */
+  function testEntityFieldQueryTableSort() {
+    // Test TableSort in propertyQuery
+    $_GET['sort'] = 'asc';
+    $_GET['order'] = 'Id';
+    $header = array(
+      'id' => array('data' => 'Id', 'type' => 'property',  'specifier' => 'ftid'),
+      'type' => array('data' => 'Type', 'type' => 'entity', 'specifier' => 'bundle'),
+    );
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
+    ), t('Test TableSort by property: ftid ASC in propertyQuery.'), TRUE);
+    
+    $_GET['sort'] = 'desc';
+    $_GET['order'] = 'Id';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 6),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 1),
+    ), t('Test TableSort by property: ftid DESC in propertyQuery.'), TRUE);
+    
+    $_GET['sort'] = 'asc';
+    $_GET['order'] = 'Type';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
+    ), t('Test TableSort by entity: bundle ASC in propertyQuery.'), TRUE);
+    
+    $_GET['sort'] = 'desc';
+    $_GET['order'] = 'Type';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+    ), t('Test TableSort by entity: bundle DESC in propertyQuery.'), TRUE);
+    
+    // Test TableSort in field storage
+    $_GET['sort'] = 'asc';
+    $_GET['order'] = 'Id';
+    $header = array(
+      'id' => array('data' => 'Id', 'type' => 'property',  'specifier' => 'ftid'),
+      'type' => array('data' => 'Type', 'type' => 'entity', 'specifier' => 'bundle'),
+      'field' => array('data' => 'Field', 'type' => 'field', 'specifier' => array('field' => $this->field_names[0], 'column' => 'value')),
+    );
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
+    ), t('Test TableSort by property: ftid ASC in field storage.'), TRUE);
+
+    $_GET['sort'] = 'desc';
+    $_GET['order'] = 'Id';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 6),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 1),
+    ), t('Test TableSort by property: ftid DESC in field storage.'), TRUE);
+
+    $_GET['sort'] = 'asc';
+    $_GET['order'] = 'Type';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->tableSort($header)
+      ->entityOrderBy('entity_id', 'DESC');
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 6),
+      array('test_entity_bundle_key', 5),
+    ), t('Test TableSort by entity: bundle ASC in field storage.'), TRUE);
+
+    $_GET['sort'] = 'desc';
+    $_GET['order'] = 'Type';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->tableSort($header)
+      ->entityOrderBy('entity_id', 'ASC');
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+    ), t('Test TableSort by entity: bundle DESC in field storage.'), TRUE);
+
+    $_GET['sort'] = 'asc';
+    $_GET['order'] = 'Field';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
+    ), t('Test TableSort by field ASC.'), TRUE);
+
+    $_GET['sort'] = 'desc';
+    $_GET['order'] = 'Field';
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'test_entity_bundle_key')
+      ->fieldCondition($this->fields[0], 'value', 0, '>')
+      ->tableSort($header);
+    $this->assertEntityFieldQuery($query, array(
+      array('test_entity_bundle_key', 6),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 1),
+    ), t('Test TableSort by field DESC.'), TRUE);
+
+    unset($_GET['sort']);
+    unset($_GET['order']);
+  }
 
   /**
    * Fetches the results of an EntityFieldQuery and compares.
