diff --git a/includes/display-edit.inc b/includes/display-edit.inc
index dc6d1b9..4848e16 100644
--- a/includes/display-edit.inc
+++ b/includes/display-edit.inc
@@ -246,6 +246,16 @@ function panels_edit_display_settings_form($form, &$form_state) {
       '#maxlength' => 255,
     );
 
+    $form['display_title']['title_url'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $display->title_url,
+      '#title' => t('Title URL'),
+      '#description' => t('The URL for the title of this panel. If left blank, no link will be generated.'),
+      '#process' => array('ctools_dependent_process'),
+      '#dependency' => array('edit-display-title-hide-title' => array(PANELS_TITLE_FIXED)),
+      '#maxlength' => 255,
+    );
+
     if (!empty($display->context)) {
       $form['display_title']['title']['#description'] .= ' ' . t('You may use substitutions in this title.');
 
@@ -324,5 +334,6 @@ function panels_edit_display_settings_form_submit($form, &$form_state) {
   if (isset($form_state['values']['display_title']['title'])) {
     $display->title = $form_state['values']['display_title']['title'];
     $display->hide_title = $form_state['values']['display_title']['hide_title'];
+    $display->title_url = $form_state['values']['display_title']['title_url'];
   }
 }
diff --git a/panels.install b/panels.install
index ab4d193..ba1f5da 100644
--- a/panels.install
+++ b/panels.install
@@ -47,7 +47,19 @@ function panels_requirements_install() {
 function panels_schema() {
   // This should always point to our 'current' schema. This makes it relatively
   // easy to keep a record of schema as we make changes to it.
-  return panels_schema_6();
+  return panels_schema_7();
+}
+
+function panels_schema_7() {
+  $schema = panels_schema_6();
+
+  $schema['panels_display']['fields']['title_url'] = array(
+    'type' => 'varchar',
+    'length' => '255',
+    'default' => '',
+  );
+
+  return $schema;
 }
 
 function panels_schema_6() {
@@ -383,7 +395,6 @@ function panels_update_7300() {
  */
 function panels_update_7301() {
   // Load the schema.
-
   // Due to a previous failure, the field may already exist:
 
   $schema = panels_schema_4();
@@ -487,3 +498,22 @@ function panels_update_7303() {
     db_create_table($table_name, $schema[$table_name]);
   }
 }
+
+/**
+ * Add panels_display.title_url field.
+ */
+function panels_update_7304() {
+  // Load the schema.
+  $schema = panels_schema_7();
+  $table = 'panels_display';
+  $field = 'title_url';
+  $spec = $schema[$table]['fields'][$field];
+
+  if (!db_field_exists($table, $field)) {
+    // Re-define the column.
+    db_add_field($table, $field, $spec);
+    return t('Added panels_display.title_url field.');
+  }
+
+  return t('panels_pane.title_url field already existed, update skipped.');
+}
diff --git a/panels.module b/panels.module
index 4bb3bad..381bf04 100644
--- a/panels.module
+++ b/panels.module
@@ -705,7 +705,14 @@ class panels_display {
 
       case PANELS_TITLE_FIXED:
       case FALSE; // For old exported panels that are not in the database.
-        if (!empty($this->title)) {
+        if (!empty($this->title) && !empty($this->title_url)) {
+          return l(
+            filter_xss_admin(ctools_context_keyword_substitute($this->title, array(), $this->context)),
+            filter_xss_admin(ctools_context_keyword_substitute($this->title_url, array(), $this->context)),
+            array('attributes' => array('class' => 'title-link'))
+          );
+        }
+        elseif (!empty($this->title)) {
           return filter_xss_admin(ctools_context_keyword_substitute($this->title, array(), $this->context));
         }
         return NULL;
