diff --git a/twitter_post/plugins/content_types/twitter_post.inc b/twitter_post/plugins/content_types/twitter_post.inc
new file mode 100644
index 0000000..048e221
--- /dev/null
+++ b/twitter_post/plugins/content_types/twitter_post.inc
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @file
+ * Display the node form's Twitter fieldset in a Panels pane.
+ */
+
+$plugin = array(
+  'single' => TRUE,
+  'title' => t('Post to Twitter'),
+  'icon' => 'icon_node_form.png',
+  'description' => t('Optionally post a message to Twitter announcing the node.'),
+  'required context' => new ctools_context_required(t('Form'), 'node_form'),
+  'category' => t('Form'),
+);
+
+/**
+ * CTools content type callback to output this pane.
+ */
+function twitter_post_twitter_post_content_type_render($subtype, $conf, $panel_args, &$context) {
+  $block = new stdClass();
+
+  $block->title = t('Post to Twitter');
+  $block->module = 'twitter_post';
+  $block->delta = 'twitter_post';
+
+  if (isset($context->form)) {
+    if (isset($context->form['twitter'])) {
+      $block->content['twitter'] = $context->form['twitter'];
+      unset($block->content['twitter']['#pre_render']);
+      unset($block->content['twitter']['#theme_wrappers']);
+      $block->content['twitter']['#type'] = '';
+
+      // Set access to false on the original rather than removing so that
+      // vertical tabs doesn't clone it. I think this is due to references.
+      $context->form['twitter']['#access'] = FALSE;
+    }
+  }
+  else {
+    $block->content = t('Post to Twitter.');
+  }
+  return $block;
+}
+
+/**
+ * CTools content type callback to get the title of this pane.
+ */
+function twitter_post_twitter_post_content_type_admin_title($subtype, $conf, $context) {
+  if (isset($context->identifier)) {
+    $message = t('"@s" node form "Post to Twitter" options', array('@s' => $context->identifier));
+  }
+  else {
+    $message = t('Node form "Post to Twitter" options');
+  }
+  return $message;
+}
+
+/**
+ * CTools content type callback to display an edit form for this pane.
+ */
+function twitter_post_twitter_post_content_type_edit_form($form, &$form_state) {
+  // Provide a blank form so we have a place to have context setting.
+  return $form;
+}
+
+/**
+ * CTools content type callback to provide extra information about this pane.
+ */
+function twitter_post_twitter_post_content_type_admin_info($type, $subtype, $conf, $context = NULL) {
+  $output = new stdClass();
+  $output->title = t('Post to Twitter');
+  $output->content = t('Shows the "Post to Twitter" fields on this node form, if the user has the necessary permission, and either they have added a Twitter account to their site account or there are some Twitter accounts added to the site which are marked as being "Global".');
+
+  return $output;
+}
diff --git a/twitter_post/twitter_post.module b/twitter_post/twitter_post.module
index 78ce0cb..03611b7 100644
--- a/twitter_post/twitter_post.module
+++ b/twitter_post/twitter_post.module
@@ -33,6 +33,15 @@ function twitter_post_permission() {
 }
 
 /**
+ * Implements hook_ctools_plugin_directory().
+ */
+function twitter_post_ctools_plugin_directory($owner, $plugin_type) {
+  if ($owner == 'ctools' && $plugin_type == 'content_types') {
+    return "plugins/$plugin_type";
+  }
+}
+
+/**
  * Implements hook_form_FORM_ID_alter() for node_type_form().
  */
 function twitter_post_form_node_type_form_alter(&$form, $form_state, $form_id) {
