diff --git a/privatemsg.info b/privatemsg.info
index cf9dfb3..1023b53 100644
--- a/privatemsg.info
+++ b/privatemsg.info
@@ -5,6 +5,9 @@ core = 7.x
 files[] = privatemsg.module
 files[] = privatemsg.test
 files[] = views/views_handler_field_privatemsg_link.inc
+files[] = views/views_handler_field_pm_body.inc
+files[] = views/views_handler_field_pm_subject.inc
+files[] = views/views_handler_field_pm_thread_link.inc
 files[] = views/privatemsg.views.inc
 files[] = privatemsg.theme.inc
 files[] = privatemsg.pages.inc
diff --git a/views/privatemsg.views.inc b/views/privatemsg.views.inc
index 84d4807..5f29d28 100644
--- a/views/privatemsg.views.inc
+++ b/views/privatemsg.views.inc
@@ -18,6 +18,213 @@ function privatemsg_views_data() {
       'handler' => 'views_handler_field_privatemsg_link',
     ),
   );
+
+  $data['pm_message']['table']['group'] = t('Privatemsg');
+
+  $data['pm_message']['table']['base'] = array(
+    'field' => 'mid',
+    'title' => t('Private messages'),
+    'help' => t('Private messages sent between users.'),
+    'defaults' => array(
+      'field' => 'body',
+    ),
+  );
+
+  $data['pm_message']['table']['entity type'] = 'privatemsg_message';
+
+  $data['pm_message']['table']['join'] = array(
+    'pm_index' => array(
+      'left_table' => 'pm_index',
+      'left_field' => 'mid',
+      'field' => 'mid',
+    ),
+  );
+
+  $data['pm_message']['mid'] = array(
+    'title' => t('Message ID'),
+    'help' => t('The private message ID.'),
+    'field' => array(
+      'handler' => 'views_handler_field_numeric',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'relationship' => array(
+      'base' => 'pm_index',
+      'field' => 'mid',
+      'handler' => 'views_handler_relationship',
+      'label' => t('Message index'),
+      'title' => t('Message index'),
+      'help' => t('Relate the message to threading info.'),
+    ),
+  );
+
+  $data['pm_message']['author'] = array(
+    'title' => t('Author'),
+    'help' => t('The private message author.'),
+    'field' => array(
+      'help' => t('The UID of the private message author.'),
+      'handler' => 'views_handler_field_numeric',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'relationship' => array(
+      'base' => 'users',
+      'field' => 'author',
+      'handler' => 'views_handler_relationship',
+      'label' => t('Author'),
+      'help' => t('Relate to the user who sent the private message.'),
+    ),
+  );
+
+  $data['pm_message']['subject'] = array(
+    'title' => t('Subject'),
+    'help' => t('The subject of the private message.'),
+    'field' => array(
+      'handler' => 'views_handler_field_pm_subject',
+      'format' => 'plain_text',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+  $data['pm_message']['body'] = array(
+    'title' => t('Message'),
+    'help' => t('The text of the private message.'),
+    'field' => array(
+      'handler' => 'views_handler_field_pm_body',
+      'format' => array('field' => 'format'),
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+  $data['pm_message']['timestamp'] = array(
+    'title' => t('Send date'),
+    'help' => t('The date and time when the message was sent.'),
+    'field' => array(
+      'handler' => 'views_handler_field_date',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_date',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort_date',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_date',
+    ),
+  );
+
+  $data['pm_index']['table']['group'] = t('Privatemsg');
+
+  $data['pm_index']['table']['base'] = array(
+    'field' => 'mid',
+    'title' => t('Privatemsg threading index'),
+    'defaults' => array(
+      'field' => 'thread_id',
+    ),
+  );
+
+  $data['pm_index']['table']['join'] = array(
+    'pm_message' => array(
+      'left_table' => 'pm_message',
+      'left_field' => 'mid',
+      'field' => 'mid',
+    ),
+  );
+
+  $data['pm_index']['table']['entity type'] = 'privatemsg_message';
+
+  $data['pm_index']['thread_id'] = array(
+    'title' => t('Thread ID'),
+    'help' => t('The ID of the private message thread.'),
+    'field' => array(
+      'handler' => 'views_handler_field_numeric',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'argument' => array(
+      'help' => t('Filter according to the thread privatemsgs belong to.'),
+      'handler' => 'views_handler_argument_many_to_one',
+    ),
+  );
+  $data['pm_index']['thread_link'] = array(
+    'real field' => 'thread_id',
+    'title' => t('Link to thread'),
+    'help' => t('A link to the private message thread.'),
+    'field' => array(
+      'handler' => 'views_handler_field_pm_thread_link',
+    ),
+  );
+  $data['pm_index']['recipient'] = array(
+    'title' => t('Recipient'),
+    'field' => array(
+      'help' => t('The UID of the private message recipient.'),
+      'handler' => 'views_handler_field_numeric',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'argument' => array(
+      'help' => t("Filter according to the recipient's uid."),
+      'handler' => 'views_handler_argument_user_uid',
+    ),
+    'relationship' => array(
+      'base' => 'users',
+      'field' => 'recipient',
+      'handler' => 'views_handler_relationship',
+      'label' => t('Recipient'),
+      'help' => t('Relate to the user receiving the private message.'),
+    ),
+  );
+  $data['pm_index']['is_new'] = array(
+    'title' => t('Is new'),
+    'help' => t('Whether the private message is unread.'),
+    'field' => array(
+      'handler' => 'views_handler_field_boolean',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'help' => t('Filter to private messages that have/have not been read.'),
+      'handler' => 'views_handler_filter_boolean_operator',
+      'label' => t('Show new'),
+      'type' => 'yes-no',
+    ),
+  );
+  $data['pm_index']['deleted'] = array(
+    'title' => t('Is deleted'),
+    'help' => t('Whether the private message has been deleted.'),
+    'field' => array(
+      'handler' => 'views_handler_field_boolean',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'help' => t('Filter to private messages that have/have not been deleted.'),
+      'handler' => 'views_handler_filter_boolean_operator',
+      'label' => t('Show deleted'),
+      'type' => 'yes-no',
+    ),
+  );
+
   return $data;
 }
-
diff --git a/views/views_handler_field_pm_body.inc b/views/views_handler_field_pm_body.inc
new file mode 100644
index 0000000..cf88358
--- /dev/null
+++ b/views/views_handler_field_pm_body.inc
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \views_handler_field_pm_body.
+ */
+
+/**
+ * Defines a field handler that renders private message body.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_pm_body extends views_handler_field_markup {
+
+  /**
+   * Constructor; calls to base object constructor.
+   */
+  function construct() {
+    parent::construct();
+    // Add fields to run token replacement when needed.
+    $this->additional_fields['has_tokens'] = 'has_tokens';
+    $this->additional_fields['mid'] = 'mid';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function render($values) {
+    $value = $this->get_value($values);
+    if ($value) {
+      if (is_array($this->format)) {
+        $format = $this->get_value($values, 'format');
+      }
+      else {
+        $format = $this->format;
+      }
+      $value = check_markup($value, $format, '');
+      if ($this->get_value($values, 'has_tokens') && ($mid = $this->get_value($values, 'mid'))) {
+        // Apply internal token replacement.
+        if ($privatemsg = privatemsg_message_load($mid)) {
+          $value = privatemsg_token_replace($value, array('privatemsg_message' => $privatemsg), array('privatemsg-show-span' => FALSE));
+        }
+      }
+      return $value;
+    }
+  }
+
+}
diff --git a/views/views_handler_field_pm_subject.inc b/views/views_handler_field_pm_subject.inc
new file mode 100644
index 0000000..818ffbc
--- /dev/null
+++ b/views/views_handler_field_pm_subject.inc
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \views_handler_field_pm_subject.
+ */
+
+/**
+ * Defines a field handler that renders private message subject.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_pm_subject extends views_handler_field_markup {
+
+  /**
+   * Constructor; calls to base object constructor.
+   */
+  function construct() {
+    parent::construct();
+    // Add fields to run token replacement when needed.
+    $this->additional_fields['has_tokens'] = 'has_tokens';
+    $this->additional_fields['mid'] = 'mid';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function render($values) {
+    $value = $this->get_value($values);
+    if ($value) {
+      $value = check_plain($value);
+      if ($this->get_value($values, 'has_tokens') && ($mid = $this->get_value($values, 'mid'))) {
+        // Apply internal token replacement.
+        if ($privatemsg = privatemsg_message_load($mid)) {
+          $value = privatemsg_token_replace($value, array('privatemsg_message' => $privatemsg), array('privatemsg-show-span' => FALSE));
+        }
+      }
+      return $value;
+    }
+  }
+
+}
diff --git a/views/views_handler_field_pm_thread_link.inc b/views/views_handler_field_pm_thread_link.inc
new file mode 100644
index 0000000..79d332e
--- /dev/null
+++ b/views/views_handler_field_pm_thread_link.inc
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \views_handler_field_pm_thread_link.
+ */
+
+/**
+ * Provides a field handler that renders a link to the private message thread.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_pm_thread_link extends views_handler_field {
+
+  /**
+   * {@inheritdoc}
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['link_text'] = array('default' => t('View thread'), 'translatable' => TRUE);
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['link_text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Link text'),
+      '#description' => t('The text to show in the link'),
+      '#default_value' => $this->options['link_text'],
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function access() {
+    return privatemsg_user_access();
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
+  function render($values) {
+    $value = $this->get_value($values);
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = 'messages/view/' . $value;
+    return $this->sanitize_value($this->options['link_text']);
+  }
+
+}
diff --git a/views/views_handler_field_privatemsg_link.inc b/views/views_handler_field_privatemsg_link.inc
index d6dca89..56cec4c 100644
--- a/views/views_handler_field_privatemsg_link.inc
+++ b/views/views_handler_field_privatemsg_link.inc
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains the privatemsg link views field handler.
+ * Contains \views_handler_field_pm_thread_link.
  */
 
 /**
@@ -177,4 +177,4 @@ class views_handler_field_privatemsg_link extends views_handler_field {
     $this->ensure_my_table();
     $this->add_additional_fields();
   }
-}
\ No newline at end of file
+}
