diff --git a/contrib/profile2_page.inc b/contrib/profile2_page.inc
index f3bb8b5..e6a11ad 100644
--- a/contrib/profile2_page.inc
+++ b/contrib/profile2_page.inc
@@ -30,53 +30,6 @@ function profile2_page_view($profile) {
 }
 
 /**
- * The profile edit form.
- */
-function profile2_form($form, &$form_state, $profile) {
-  if (empty($form_state['profiles'])) {
-    $form_state['profiles'][$profile->type] = $profile;
-  }
-  // Prevent invoking the same hooks twice, so tell profile2_attach_form() to
-  // skip invoking the hooks.
-  $form_state['profile2_skip_hook'] = TRUE;
-  profile2_attach_form($form, $form_state);
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-    '#weight' => 40,
-  );
-  if (empty($profile->is_new) && user_access('administer profiles')) {
-    $form['actions']['delete'] = array(
-      '#type' => 'submit',
-      '#value' => t('Delete profile'),
-      '#weight' => 45,
-      '#limit_validation_errors' => array(),
-      '#submit' => array('profile2_form_submit_delete')
-    );
-  }
-  $form['#submit'][] = 'profile2_form_submit';
-  return $form;
-}
-
-/**
- * Profile form submit handler.
- */
-function profile2_form_submit($form, &$form_state) {
-  // The profile is being saved by profile2_form_submit_handler().
-  drupal_set_message(t('The changes have been saved.'));
-  $form_state['redirect'] = $form_state['profile2']->path();
-}
-
-/**
- * Profile form submit handler for the delete button.
- */
-function profile2_form_submit_delete($form, &$form_state) {
-  $form_state['redirect'] = $form_state['profile2']->path() . '/delete';
-}
-
-/**
  * Confirm form for deleting a profile.
  */
 function profile2_page_delete_confirm_form($form, &$form_state, $profile) {
diff --git a/contrib/profile2_page.module b/contrib/profile2_page.module
index 7c930fb..d5d1e1f 100644
--- a/contrib/profile2_page.module
+++ b/contrib/profile2_page.module
@@ -55,7 +55,8 @@ function profile2_page_menu() {
         'title' => 'Edit',
         'type' => MENU_LOCAL_TASK,
         'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
-        'file' => 'profile2_page.inc',
+        'file path' => drupal_get_path('module', 'profile2'),
+        'file' => 'profile2.pages.inc',
       );
       $items[$path . '/%profile2_by_uid/delete'] = array(
         'page callback' => 'drupal_get_form',
@@ -104,30 +105,16 @@ function profile2_page_get_base_path($profile_type) {
 }
 
 /**
- * Implements hook_forms().
- */
-function profile2_page_forms($form_id, $args) {
-  // For efficiency, only act if the third argument is 'profile2'.
-  if (isset($args[2]) && is_string($args[2]) && $args[2] == 'profile2') {
-    $info = entity_get_info('profile2');
-    // Translate bundle form ids to the base form id 'profile2_form'.
-    foreach ($info['bundles'] as $bundle => $bundle_info) {
-      $forms['profile2_edit_' . $bundle . '_form']['callback'] = 'profile2_form';
-      $forms['profile2_edit_' . $bundle . '_form']['wrapper callback'] = 'entity_ui_form_defaults';
-    }
-    return $forms;
-  }
-}
-
-/**
  * Implements hook_profile2_type_load().
  */
 function profile2_page_profile2_type_load($types) {
   foreach ($types as $type) {
     if (!empty($type->data['use_page'])) {
-      // Disable user categories and the user account view.
-      $type->userCategory = FALSE;
-      $type->userView = FALSE;
+      // Disable user edit tab and the user account view.
+      // @todo Remove once it has been shipped in one or two releases, so people
+      // have re-saved their profile types in the meantime.
+      $type->data['user_view'] = FALSE;
+      $type->data['user_edit_tab'] = FALSE;
     }
   }
 }
@@ -146,7 +133,6 @@ function profile2_page_entity_info_alter(&$entity_info) {
     'custom settings' => FALSE,
   );
   $entity_info['profile2']['uri callback'] = 'profile2_page_uri_callback';
-  $entity_info['profile2']['form callback'] = 'profile2_page_form_callback';
 }
 
 /**
@@ -164,15 +150,6 @@ function profile2_page_uri_callback($profile) {
 }
 
 /**
- * Form callback for entity_form().
- */
-function profile2_page_form_callback($profile) {
-  // Pre-populate the form-state with the right form include.
-  form_load_include($form_state, 'inc', 'profile2_page');
-  return entity_ui_get_form('profile2', $profile, 'edit', $form_state);
-}
-
-/**
  * Menu title callback.
  */
 function profile2_page_own_title($type_name) {
@@ -191,5 +168,34 @@ function profile2_page_form_profile2_type_form_alter(&$form, &$form_state) {
     '#description' => t('If enabled, a separate menu item for editing the profile is generated and the profile is hidden from the user account page.'),
     '#default_value' => !empty($type->is_new) || !empty($type->data['use_page']),
   );
-  $form['data']['#tree'] = TRUE;
+  // Hide the user edit tab location in case "use page" is checked.
+  $form['data']['user_edit_tab']['#states'] = array(
+    'invisible' => array(
+      ':input[name="data[use_page]"]' => array('checked' => TRUE),
+    ),
+  );
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter() for the profile2 form.
+ */
+function profile2_page_form_profile2_form_alter(&$form, &$form_state) {
+  $profile = reset($form_state['profiles']);
+  $type = $profile->type();
+  if (!empty($type->data['use_page']) && empty($profile->is_new) && user_access('administer profiles')) {
+    $form['actions']['delete'] = array(
+      '#type' => 'submit',
+      '#value' => t('Delete profile'),
+      '#weight' => 45,
+      '#limit_validation_errors' => array(),
+      '#submit' => array('profile2_form_submit_delete')
+    );
+  }
+}
+
+/**
+ * Profile form submit handler for the delete button.
+ */
+function profile2_form_submit_delete($form, &$form_state) {
+  $form_state['redirect'] = $form_state['profile2']->path() . '/delete';
 }
diff --git a/profile2.admin.inc b/profile2.admin.inc
index 4394dc0..7116633 100644
--- a/profile2.admin.inc
+++ b/profile2.admin.inc
@@ -56,6 +56,17 @@ function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') {
     '#type' => 'checkbox',
     '#title' => t('Show during user account registration.'),
     '#default_value' => !empty($profile_type->data['registration']),
+    '#weight' => -5,
+  );
+  $form['data']['user_edit_tab'] = array(
+    '#type' => 'radios',
+    '#title' => t("Edit tab location"),
+    '#default_value' => !empty($profile_type->data['user_edit_tab']) ? $profile_type->data['user_edit_tab'] : 'secondary',
+    '#options' => array(
+      'primary' => t("At the user account page (primary tab)"),
+      'secondary' => t("Below the user account's edit tab (secondary tab)"),
+    ),
+    '#weight' => 5,
   );
 
   $form['actions'] = array('#type' => 'actions');
diff --git a/profile2.api.php b/profile2.api.php
index 02cdffb..5346237 100644
--- a/profile2.api.php
+++ b/profile2.api.php
@@ -159,8 +159,8 @@ function hook_profile2_view_alter($build) {
  */
 function hook_profile2_type_load($types) {
   if (isset($types['main'])) {
-    $types['main']->userCategory = FALSE;
-    $types['main']->userView = FALSE;
+    $types['main']->data['user_edit_tab'] = FALSE;
+    $types['main']->data['user_view'] = FALSE;
   }
 }
 
diff --git a/profile2.module b/profile2.module
index d57a3c5..acd8b64 100644
--- a/profile2.module
+++ b/profile2.module
@@ -36,7 +36,8 @@ function profile2_entity_info() {
       'uri callback' => 'entity_class_uri',
       'access callback' => 'profile2_access',
       'module' => 'profile2',
-      'metadata controller class' => 'Profile2MetadataController'
+      'metadata controller class' => 'Profile2MetadataController',
+      'form callback' => 'profile2_form_callback',
     ),
   );
 
@@ -343,13 +344,12 @@ function profile2_profile2_type_delete($type) {
   menu_rebuild();
 }
 
-
 /**
  * Implements hook_user_view().
  */
 function profile2_user_view($account, $view_mode, $langcode) {
   foreach (profile2_get_types() as $type => $profile_type) {
-    if ($profile_type->userView && $profile = profile2_load_by_user($account, $type)) {
+    if ($profile_type->data['user_view'] && $profile = profile2_load_by_user($account, $type)) {
       if (profile2_access('view', $profile)) {
         $account->content['profile_' . $type] = array(
           '#type' => 'user_profile_category',
@@ -369,7 +369,7 @@ function profile2_user_view($account, $view_mode, $langcode) {
  * @see profile2_form_submit_handler
  */
 function profile2_form_user_profile_form_alter(&$form, &$form_state) {
-  if (($type = profile2_get_types($form['#user_category'])) && $type->userCategory) {
+  if (($type = profile2_get_types($form['#user_category'])) && $type->data['user_edit_tab'] == 'secondary') {
     if (empty($form_state['profiles'])) {
       $profile = profile2_load_by_user($form['#user'], $form['#user_category']);
       if (empty($profile)) {
@@ -508,12 +508,45 @@ function profile2_form_submit_cleanup(&$form, &$form_state) {
 }
 
 /**
+ * Implements hook_menu().
+ */
+function profile2_menu() {
+  $items = array();
+  foreach (profile2_get_types() as $type_name => $type) {
+    // If configured, define a menu item for the primary user tab.
+    if ($type->data['user_edit_tab'] == 'primary') {
+      $items['user/%profile2_by_uid/profile-' . $type_name] = array(
+        'title' => $type->label,
+        'page callback' => 'entity_ui_get_form',
+        'page arguments' => array('profile2', 1),
+        'load arguments' => array($type_name),
+        'access callback' => 'profile2_access',
+        'access arguments' => array('edit', 1),
+        'weight' => $type->weight + 3,
+        'type' => MENU_LOCAL_TASK,
+        'file' => 'profile2.pages.inc',
+      );
+    }
+  }
+  return $items;
+}
+
+/**
+ * Implements hook_admin_paths().
+ */
+function profile2_admin_paths() {
+  return array(
+    'user/*/profile-*' => TRUE,
+  );
+}
+
+/**
  * Implements hook_user_categories().
  */
 function profile2_user_categories() {
   $data = array();
   foreach (profile2_get_types() as $type => $info) {
-    if ($info->userCategory) {
+    if ($info->data['user_edit_tab'] == 'secondary') {
       $data[] = array(
         'name' => $type,
         'title' => $info->label,
@@ -534,7 +567,7 @@ function profile2_category_access($account, $type_name) {
   // As there might be no profile yet, create a new object for being able to run
   // a proper access check.
   $profile = profile_create(array('type' => $type_name, 'uid' => $account->uid));
-  return ($account->uid > 0 && $profile->type()->userCategory && profile2_access('edit', $profile));
+  return ($account->uid > 0 && $profile->type()->data['user_edit_tab'] == 'secondary' && profile2_access('edit', $profile));
 }
 
 /**
@@ -709,19 +742,39 @@ class Profile extends Entity {
 class ProfileType extends Entity {
 
   /**
-   * Whether the profile type appears in the user categories.
+   * The profile type name.
    */
-  public $userCategory = TRUE;
+  public $type;
 
   /**
-   * Whether the profile is displayed on the user account page.
+   * The profile type label.
    */
-  public $userView = TRUE;
-
-  public $type;
   public $label;
+
+  /**
+   * The weight for sorting profile types.
+   */
   public $weight = 0;
 
+  /**
+   * Stores arbitrary data related to a profile type.
+   *
+   * The following keys are supported by profile2. Contrib modules may define
+   * further keys though:
+   *  - user_view: (optional) Whether the profile is displayed on the user
+   *    account page. Defaults to TRUE.
+   *  - user_edit_tab: (optional) The display location of the edit tab on the
+   *    user account page. 'primary' creates a tab at the user account page,
+   *    'secondary' below the user account's edit tab. FALSE disables it.
+   *    Defaults to 'secondary'.
+   *
+   * @see profile2_profile2_type_load()
+   */
+  public $data = array(
+    'user_view' => TRUE,
+    'user_edit_tab' => 'secondary'
+  );
+
   public function __construct($values = array()) {
     parent::__construct($values, 'profile2_type');
   }
@@ -738,6 +791,46 @@ class ProfileType extends Entity {
 }
 
 /**
+ * Implements hook_profile2_type_load().
+ */
+function profile2_profile2_type_load($types) {
+  foreach ($types as $type) {
+    // Make sure data-defaults are applied.
+    $type->data += array(
+      'user_view' => TRUE,
+      'user_edit_tab' => 'secondary'
+    );
+  }
+}
+
+/**
+ * Form callback for entity_form().
+ *
+ * @see profile2_entity_info()
+ */
+function profile2_form_callback($profile) {
+  // Pre-populate the form-state with the right form include.
+  form_load_include($form_state, 'inc', 'profile2', 'profile2.pages');
+  return entity_ui_get_form('profile2', $profile, 'edit', $form_state);
+}
+
+/**
+ * Implements hook_forms().
+ */
+function profile2_forms($form_id, $args) {
+  // For efficiency, only act if the third argument is 'profile2'.
+  if (isset($args[2]) && is_string($args[2]) && $args[2] == 'profile2') {
+    $info = entity_get_info('profile2');
+    // Translate bundle form ids to the base form id 'profile2_form'.
+    foreach ($info['bundles'] as $bundle => $bundle_info) {
+      $forms['profile2_edit_' . $bundle . '_form']['callback'] = 'profile2_form';
+      $forms['profile2_edit_' . $bundle . '_form']['wrapper callback'] = 'entity_ui_form_defaults';
+    }
+    return $forms;
+  }
+}
+
+/**
  * Implements hook_form_FORMID_alter().
  *
  * Adds a checkbox for controlling field view access to fields added to
diff --git a/profile2.pages.inc b/profile2.pages.inc
new file mode 100644
index 0000000..e19d4c9
--- /dev/null
+++ b/profile2.pages.inc
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Profile2 edit form.
+ */
+
+/**
+ * Builds the profile edit form.
+ *
+ * Makes use of profile2_attach_form() to build a full entity form.
+ *
+ * @see profile2_attach_form()
+ */
+function profile2_form($form, &$form_state, $profile) {
+  if (empty($form_state['profiles'])) {
+    $form_state['profiles'][$profile->type] = $profile;
+  }
+  // Prevent invoking the same hooks twice, so tell profile2_attach_form() to
+  // skip invoking the hooks.
+  $form_state['profile2_skip_hook'] = TRUE;
+  profile2_attach_form($form, $form_state);
+
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+    '#weight' => 40,
+  );
+  $form['#submit'][] = 'profile2_form_submit';
+  return $form;
+}
+
+/**
+ * Profile form submit handler.
+ */
+function profile2_form_submit($form, &$form_state) {
+  // The profile is being saved by profile2_form_submit_handler().
+  drupal_set_message(t('The changes have been saved.'));
+  $form_state['redirect'] = $form_state['profile2']->path();
+}
