diff --git a/core/includes/common.inc b/core/includes/common.inc
index 75dacc2..0381161 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6529,6 +6529,9 @@ function drupal_common_theme() {
     'pager_link' => array(
       'variables' => array('text' => NULL, 'page_new' => NULL, 'element' => NULL, 'parameters' => array(), 'attributes' => array()),
     ),
+    'pager_all' => array(
+      'variables' => array('text' => NULL, 'element' => 0, 'parameters' => array()),
+    ),
     // From menu.inc.
     'menu_link' => array(
       'render element' => 'element',
diff --git a/core/includes/pager.inc b/core/includes/pager.inc
index a5d3e6b..8076f36 100644
--- a/core/includes/pager.inc
+++ b/core/includes/pager.inc
@@ -73,7 +73,15 @@ class PagerDefault extends SelectQueryExtender {
 
     $total_items = $this->getCountQuery()->execute()->fetchField();
     $current_page = pager_default_initialize($total_items, $this->limit, $this->element);
-    $this->range($current_page * $this->limit, $this->limit);
+
+    // If the user did not click 'show all', calculate the query range.
+    // Otherwise the query can return all results.
+    if (!pager_show_all()) {
+      $this->range($current_page * $this->limit, $this->limit);
+    }
+    else {
+      $this->limit = 0;
+    }
 
     // Now that we've added our pager-based range instructions, run the query normally.
     return $this->query->execute();
@@ -194,6 +202,19 @@ function pager_find_page($element = 0) {
 }
 
 /**
+ * Determines whether to show all items in the pager.
+ * 
+ * The 'show all' behavior is used if the 'show all' link has been clicked and
+ * the current user has permission to use it.
+ * 
+ * @return
+ *   TRUE if all items should be shown, or FALSE otherwise.
+ */
+function pager_show_all() {
+  return (isset($_GET['all']) && user_access('show all items in pager')) ? TRUE : FALSE;
+}
+
+/**
  * Initializes a pager for theme('pager').
  *
  * This function sets up the necessary global variables so that future calls
@@ -324,6 +345,11 @@ function theme_pager($variables) {
   $quantity = $variables['quantity'];
   global $pager_page_array, $pager_total;
 
+  // Initialise these variables, so that we don't see 'Undefined variable'
+  // notices if the user doesn't have "show all" permission.
+  $pager_all = FALSE;
+  $li_all = NULL;
+
   // Calculate various markers within this pager piece:
   // Middle is used to "center" pages around the current page.
   $pager_middle = ceil($quantity / 2);
@@ -355,6 +381,12 @@ function theme_pager($variables) {
   $li_previous = theme('pager_previous', array('text' => (isset($tags[1]) ? $tags[1] : t('‹ previous')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
   $li_next = theme('pager_next', array('text' => (isset($tags[3]) ? $tags[3] : t('next ›')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
   $li_last = theme('pager_last', array('text' => (isset($tags[4]) ? $tags[4] : t('last »')), 'element' => $element, 'parameters' => $parameters));
+  // Only display the 'show all' link to users with permission.
+  if (user_access('show all items in pager')) {
+    // Check if the user has clicked 'show all'.
+    $pager_all = pager_show_all();
+    $li_all = theme('pager_all', array('text' => (isset($tags[5]) ? $tags[5] : t('show all')), 'element' => $element, 'parameters' => $parameters));
+  }
 
   if ($pager_total[$element] > 1) {
     if ($li_first) {
@@ -363,7 +395,7 @@ function theme_pager($variables) {
         'data' => $li_first,
       );
     }
-    if ($li_previous) {
+    if ($li_previous && !$pager_all) {
       $items[] = array(
         'class' => array('pager-previous'),
         'data' => $li_previous,
@@ -371,7 +403,7 @@ function theme_pager($variables) {
     }
 
     // When there is more than one page, create the pager list.
-    if ($i != $pager_max) {
+    if ($i != $pager_max && !$pager_all) {
       if ($i > 1) {
         $items[] = array(
           'class' => array('pager-ellipsis'),
@@ -407,7 +439,7 @@ function theme_pager($variables) {
       }
     }
     // End generation.
-    if ($li_next) {
+    if ($li_next && !$pager_all) {
       $items[] = array(
         'class' => array('pager-next'),
         'data' => $li_next,
@@ -419,6 +451,12 @@ function theme_pager($variables) {
         'data' => $li_last,
       );
     }
+    if ($li_all && !$pager_all) {
+      $items[] = array(
+        'class' => array('pager-all'),
+        'data' => $li_all,
+      );
+    }
     return '<h2 class="element-invisible">' . t('Pages') . '</h2>' . theme('item_list', array(
       'items' => $items,
       'attributes' => array('class' => array('pager')),
@@ -455,8 +493,8 @@ function theme_pager_first($variables) {
   global $pager_page_array;
   $output = '';
 
-  // If we are anywhere but the first page
-  if ($pager_page_array[$element] > 0) {
+  // If we are anywhere but the first page OR we're showing all items.
+  if ($pager_page_array[$element] > 0 || pager_show_all()) {
     $output = theme('pager_link', array('text' => $text, 'page_new' => pager_load_array(0, $element, $pager_page_array), 'element' => $element, 'parameters' => $parameters));
   }
 
@@ -611,6 +649,11 @@ function theme_pager_link($variables) {
     $query = array_merge($query, $query_pager);
   }
 
+  // The 'show all' query parameter should never be included on the other links.
+  if (pager_show_all()) {
+    unset($query['all']);
+  }
+
   // Set each pager link title
   if (!isset($attributes['title'])) {
     static $titles = NULL;
@@ -620,6 +663,7 @@ function theme_pager_link($variables) {
         t('‹ previous') => t('Go to previous page'),
         t('next ›') => t('Go to next page'),
         t('last »') => t('Go to last page'),
+        t('show all') => t('Show all items on one page'),
       );
     }
     if (isset($titles[$text])) {
@@ -634,6 +678,35 @@ function theme_pager_link($variables) {
 }
 
 /**
+ * Returns HTML for the 'show all' link in query pager.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - text: The name (or image) of the link.
+ *   - element: An optional integer to distinguish between multiple pagers on
+ *     one page.
+ *   - parameters: An associative array of query string parameters to append to
+ *     the pager links.
+ *
+ * @ingroup themeable
+ */
+function theme_pager_all($variables) {
+  $text = $variables['text'];
+  $element = $variables['element'];
+  $parameters = $variables['parameters'];
+  global $pager_page_array, $pager_total;
+  $output = '';
+
+  // Add 'all' to the query string.
+  $parameters['all'] = TRUE;
+
+  // Unless we're already showing all items
+  $output = theme('pager_link', array('text' => $text, NULL, 'element' => $element, 'parameters' => $parameters));
+
+  return $output;
+}
+
+/**
  * @} End of "Pager pieces".
  */
 
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index e2e16ae..a30e402 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -239,6 +239,9 @@ function system_permission() {
     'block IP addresses' => array(
       'title' => t('Block IP addresses'),
     ),
+    'show all items in pager' => array(
+      'title' => t('Access "show all" functionality in pagers'),
+    ),
   );
 }
 
