diff --git a/panelizer.module b/panelizer.module
index 4820ac6..90b65b1 100644
--- a/panelizer.module
+++ b/panelizer.module
@@ -592,13 +592,15 @@ function panelizer_get_plugins_with_hook($hook) {
  */
 function panelizer_entity_plugin_switcher_page($entity_type, $op) {
   $args = func_get_args();
-  $js = !empty($_REQUEST['js']);
 
   // Load the $plugin information
   if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
     // replace the first two arguments:
-    $args[0] = $js;
+    $args[0] = !empty($_REQUEST['js']);
     $args[1] = $_POST;
+    if (empty($args[3])) {
+      $args[3] = 'page_manager';
+    }
     $method = 'page_' . $op;
     if (method_exists($handler, $method)) {
       return call_user_func_array(array($handler, $method), $args);
@@ -1073,7 +1075,7 @@ function panelizer_context_cache_clear($entity_type, $key) {
 function panelizer_panels_cache_get($argument) {
   ctools_include('object-cache');
   list($entity_type, $key) = explode(':', $argument, 2);
-  $cache = ctools_object_cache_get('panelizer_display_cache', $entity_type . ':' . $key);
+  $cache = ctools_object_cache_get('panelizer_display_cache', $argument);
 
   // Keep $type because $entity_type can be 'default' which is not actually an
   // entity type in that case.
@@ -1088,6 +1090,13 @@ function panelizer_panels_cache_get($argument) {
     return;
   }
 
+  if ($handler->supports_revisions) {
+    list($entity_id, $view_mode, $vid) = explode(':', $key);
+  }
+  else {
+    list($entity_id, $view_mode) = explode(':', $key);
+  }
+
   // If it's already cached, we still need to restore our contexts.
   if (!empty($cache)) {
     $cache->cached = TRUE;
@@ -1096,8 +1105,8 @@ function panelizer_panels_cache_get($argument) {
       $cache->display->context = $handler->get_contexts($panelizer);
     }
     else {
-      list($entity_id, $view_mode) = explode(':', $key);
-      $entities = entity_load($entity_type, array($entity_id));
+      $conditions = (isset($vid) ? array('vid' => $vid) : array());
+      $entities = entity_load($entity_type, array($entity_id), $conditions);
       if (!empty($entities[$entity_id]) && !empty($entities[$entity_id]->panelizer[$view_mode])) {
         $panelizer = $entities[$entity_id]->panelizer[$view_mode];
         $cache->display->context = $handler->get_contexts($panelizer, $entities[$entity_id]);
@@ -1116,8 +1125,8 @@ function panelizer_panels_cache_get($argument) {
     $cache->display->context = $handler->get_contexts($panelizer);
   }
   else {
-    list($entity_id, $view_mode) = explode(':', $key);
-    $entities = entity_load($entity_type, array($entity_id));
+    $conditions = (isset($vid) ? array('vid' => $vid) : array());
+    $entities = entity_load($entity_type, array($entity_id), $conditions);
     if (empty($entities[$entity_id]) || empty($entities[$entity_id]->panelizer[$view_mode])) {
       return $cache;
     }
@@ -1130,7 +1139,7 @@ function panelizer_panels_cache_get($argument) {
 
   ctools_include('common', 'panels');
   ctools_include('plugins', 'panels');
-  $cache->display->cache_key = "panelizer:$type:$key";
+  $cache->display->cache_key = "panelizer:$type:$key" . (!empty($vid) && is_numeric($vid) ? ":$vid" : '');
 
   // Set the allowed content types
   if (variable_get('panelizer_' . $type . ':' . $bundle . '_allowed_types_default', FALSE)) {
@@ -1155,18 +1164,16 @@ function panelizer_panels_cache_get($argument) {
  * Store a display edit in progress in the page cache.
  */
 function panelizer_panels_cache_set($argument, $cache) {
-  list($type, $key) = explode(':', $argument, 2);
   ctools_include('object-cache');
-  ctools_object_cache_set('panelizer_display_cache', $type . ':' . $key, $cache);
+  ctools_object_cache_set('panelizer_display_cache', $argument, $cache);
 }
 
 /**
  * Save all changes made to a display using the Page Manager page cache.
  */
 function panelizer_panels_cache_clear($argument, $cache) {
-  list($type, $key) = explode(':', $argument, 2);
   ctools_include('object-cache');
-  ctools_object_cache_clear('panelizer_display_cache', $type . ':' . $key);
+  ctools_object_cache_clear('panelizer_display_cache', $argument);
 }
 
 /**
@@ -1192,6 +1199,9 @@ function panelizer_panels_cache_save($argument, $cache) {
     return;
   }
 
+  if ($handler->supports_revisions) {
+    list($key, $vid) = explode(':', $key, 2);
+  }
 
   if (!empty($get_default)) {
     $panelizer = $handler->get_default_panelizer_object($bundle, $name);
@@ -1201,7 +1211,8 @@ function panelizer_panels_cache_save($argument, $cache) {
   }
   else {
     list($entity_id, $view_mode) = explode(':', $key);
-    $entities = entity_load($entity_type, array($entity_id));
+    $conditions = (isset($vid) ? array('vid' => $vid) : array());
+    $entities = entity_load($entity_type, array($entity_id), $conditions);
     if ($entities[$entity_id] && $entities[$entity_id]->panelizer[$view_mode]) {
       $entities[$entity_id]->panelizer[$view_mode]->display = $cache->display;
       $entities[$entity_id]->panelizer[$view_mode]->display_is_modified = TRUE;
@@ -1585,3 +1596,24 @@ function panels_ipe_revert_to_default($form, &$form_state) {
 
   $renderer->commands[] = ajax_command_replace("#panels-ipe-display-{$renderer->clean_key}", panels_render_display($display, $renderer));
 }
+
+/**
+ * Implements hook_workbench_moderation_node_history_view_alter().
+ *
+ * This is a little kludgy as the data in the row is stored as final HTML for
+ * display.
+ */
+function panelizer_workbench_moderation_node_history_view_alter(&$rows) {
+  foreach ($rows as $key => &$row) {
+    $published = FALSE;
+    if (in_array('published-revision', $row['class'])) {
+      $published = TRUE;
+    }
+    if ($published) {
+      $row['data']['revision'] .= ' | ' . l('Panelizer', 'node/' . arg(1) . '/panelizer');
+    }
+    else {
+      $row['data']['revision'] .= ' | ' . l('Panelizer', 'node/' . arg(1) . '/revisions/' . $row['data']['vid'] . '/panelizer');
+    }
+  }
+}
diff --git a/plugins/entity/PanelizerEntityDefault.class.php b/plugins/entity/PanelizerEntityDefault.class.php
index 797b35e..3c3b821 100644
--- a/plugins/entity/PanelizerEntityDefault.class.php
+++ b/plugins/entity/PanelizerEntityDefault.class.php
@@ -265,6 +265,7 @@ abstract class PanelizerEntityDefault implements PanelizerEntityInterface {
 
       // Configure entity editing pages
       $base = array(
+        'page callback' => 'panelizer_entity_plugin_switcher_page',
         'access callback' => 'panelizer_entity_plugin_callback_switcher',
         'access arguments' => array($this->entity_type, 'access', 'admin', $position, 'overview'),
         'type' => MENU_LOCAL_TASK,
@@ -272,36 +273,66 @@ abstract class PanelizerEntityDefault implements PanelizerEntityInterface {
 
       $items[$this->plugin['entity path'] . '/panelizer'] = array(
         'title' => 'Panelizer',
-        // make sure this is accessible to panelize entities with no defaults.
-        'page callback' => 'panelizer_entity_plugin_switcher_page',
+        // Make sure this is accessible to panelize entities with no defaults.
         'page arguments' => array($this->entity_type, 'overview', $position),
-        'weight' => 11,
         'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
+        'weight' => 11,
       ) + $base;
 
       $items[$this->plugin['entity path'] . '/panelizer/overview'] = array(
         'title' => 'Overview',
-        'page callback' => 'panelizer_entity_plugin_switcher_page',
         'page arguments' => array($this->entity_type, 'overview', $position),
         'type' => MENU_DEFAULT_LOCAL_TASK,
-        'weight' => 11,
+        'weight' => -100,
       ) + $base;
 
+      if ($this->supports_revisions) {
+        $rev_base = $base;
+        $rev_base['load arguments'] = array($position + 2);
+        $items[$this->plugin['entity path'] . '/revisions/%/panelizer'] = array(
+          'title' => 'Panelizer',
+          // Make sure this is accessible to panelize entities with no defaults.
+          'page arguments' => array($this->entity_type, 'overview', $position),
+          'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
+          'type' => MENU_LOCAL_TASK,
+          'weight' => 11,
+        ) + $rev_base;
+
+        // Integration with Workbench Moderation.
+        if (module_exists('workbench_moderation') && $this->entity_type == 'node') {
+          $items[$this->plugin['entity path'] . '/revisions/%/panelizer']['type'] = MENU_CALLBACK;
+        }
+
+        $items[$this->plugin['entity path'] . '/revisions/%/panelizer/overview'] = array(
+          'title' => 'Overview',
+          'page arguments' => array($this->entity_type, 'overview', $position),
+          'type' => MENU_DEFAULT_LOCAL_TASK,
+          'weight' => -100,
+        ) + $rev_base;
+      }
+
       // Put in all of our view mode based paths.
       $weight = 0;
       foreach ($this->plugin['view modes'] as $view_mode => $view_mode_info) {
-        $items[$this->plugin['entity path'] . "/panelizer/$view_mode"] = array(
+        $items[$this->plugin['entity path'] . '/panelizer/' . $view_mode] = array(
           'title' => $view_mode_info['label'],
-          'page callback' => 'panelizer_entity_plugin_switcher_page',
           'page arguments' => array($this->entity_type, 'settings', $position, $view_mode),
           'access arguments' => array($this->entity_type, 'access', 'admin', $position, 'settings', $view_mode),
           'weight' => $weight++,
         ) + $base;
 
+        if ($this->supports_revisions) {
+          $items[$this->plugin['entity path'] . '/revisions/%/panelizer/' . $view_mode] = array(
+            'title' => $view_mode_info['label'],
+            'page arguments' => array($this->entity_type, 'content', $position, $view_mode),
+            'access arguments' => array($this->entity_type, 'access', 'admin', $position, 'content', $view_mode),
+            'weight' => $weight++,
+          ) + $base;
+        }
+
         foreach (panelizer_operations() as $path => $operation) {
           $items[$this->plugin['entity path'] . '/panelizer/' . $view_mode . '/' . $path] = array(
             'title' => $operation['menu title'],
-            'page callback' => 'panelizer_entity_plugin_switcher_page',
             'page arguments' => array($this->entity_type, $path, $position, $view_mode),
             'access arguments' => array($this->entity_type, 'access', 'admin', $position, $path, $view_mode),
             'weight' => $weight++,
@@ -320,6 +351,22 @@ abstract class PanelizerEntityDefault implements PanelizerEntityInterface {
           'page arguments' => array($this->entity_type, 'reset', $position, $view_mode),
           'type' => MENU_CALLBACK,
         ) + $base;
+
+        if ($this->supports_revisions) {
+          $items[$this->plugin['entity path'] . '/revisions/%/panelizer/' . $view_mode . '/' . $path] = array(
+            'title' => $operation['menu title'],
+            'page arguments' => array($this->entity_type, $path, $position, $view_mode),
+            'access arguments' => array($this->entity_type, 'access', 'admin', $position, $path, $view_mode),
+            'weight' => $weight++,
+          ) + $rev_base;
+        
+          if (isset($operation['file'])) {
+            $items[$this->plugin['entity path'] . '/revisions/%/panelizer/' . $view_mode . '/' . $path]['file'] = $operation['file'];
+          }
+          if (isset($operation['file path'])) {
+            $items[$this->plugin['entity path'] . '/revisions/%/panelizer/' . $view_mode . '/' . $path]['file path'] = $operation['file path'];
+          }
+        }
       }
     }
 
@@ -789,8 +836,14 @@ abstract class PanelizerEntityDefault implements PanelizerEntityInterface {
             $dids[$entity->panelizer[$view_mode]->did] = $entity->panelizer[$view_mode]->did;
           }
         }
+
+        $items[$this->plugin['entity path'] . '/panelizer/' . $view_mode . '/content']['type'] = MENU_DEFAULT_LOCAL_TASK;
+        if ($this->supports_revisions) {
+          $items[$this->plugin['entity path'] . '/revisions/%/panelizer/' . $view_mode . '/content']['type'] = MENU_DEFAULT_LOCAL_TASK;
+        }
       }
     }
+    ksort($items);
 
     // Load any defaults we collected.
     if ($defaults) {
@@ -1284,10 +1337,22 @@ abstract class PanelizerEntityDefault implements PanelizerEntityInterface {
   function entity_base_url($entity, $view_mode = NULL) {
     list($entity_id, $revision_id, $bundle) = entity_extract_ids($this->entity_type, $entity);
 
-    $bits = explode('/', $this->plugin['entity path']);
+    $path_elements[] = $entity_id;
+
+    $path = $this->plugin['entity path'];
+    if ($this->supports_revisions) {
+      $current_entities = entity_load($this->entity_type, array($entity_id));
+      $current_entity = array_pop($current_entities);
+      if ($revision_id !== $current_entity->vid) {
+        $path_elements[] = $revision_id;
+        $path .= '/revisions/%';
+      }
+    }
+
+    $bits = explode('/', $path);
     foreach ($bits as $count => $bit) {
       if (strpos($bit, '%') === 0) {
-        $bits[$count] = $entity_id;
+        $bits[$count] = array_shift($path_elements);
       }
     }
 
@@ -1334,6 +1399,12 @@ abstract class PanelizerEntityDefault implements PanelizerEntityInterface {
    * Create some fake tabs that are attached to a page output.
    */
   function make_fake_tabs($base_url, $bundle, $view_mode, $output) {
+    // Integration with Workbench Moderation: these local tabs will be
+    // automatically added via the menu system.
+    if (module_exists('workbench_moderation') && isset($bundle->workbench_moderation) && $bundle->workbench_moderation['my_revision']->vid == $bundle->workbench_moderation['current']->vid) {
+      return $output;
+    }
+
     $links_array = array();
     foreach (panelizer_operations() as $path => $operation) {
       if ($this->panelizer_access($path, $bundle, $view_mode)) {
@@ -1534,7 +1605,7 @@ abstract class PanelizerEntityDefault implements PanelizerEntityInterface {
     $form_state = array(
       'entity' => $entity,
       'revision info' => $this->entity_allows_revisions($entity),
-      'display cache' => panels_edit_cache_get(implode(':', array('panelizer', $this->entity_type, $entity_id, $view_mode))),
+      'display cache' => panels_edit_cache_get(implode(':', array('panelizer', $this->entity_type, $entity_id, $view_mode, $revision_id))),
       'no_redirect' => TRUE,
     );
 
