diff --git src/bp-core/admin/bp-core-admin-settings.php src/bp-core/admin/bp-core-admin-settings.php
index 023d2cea4..e2f4cffcc 100644
--- src/bp-core/admin/bp-core-admin-settings.php
+++ src/bp-core/admin/bp-core-admin-settings.php
@@ -203,6 +203,27 @@ function bp_admin_setting_callback_members_invitations() {
 	do_action( 'bp_admin_settings_after_members_invitations' );
 }
 
+/**
+ * Allow new users to request membership to the network.
+ *
+ * @since 10.0.0
+ */
+function bp_admin_setting_callback_membership_requests() {
+?>
+	<input id="bp-enable-membership-requests" name="bp-enable-membership-requests" type="checkbox" value="1" <?php checked( bp_get_membership_requests_required( 'raw' ) ); ?> <?php if ( bp_get_signup_allowed() ) { echo 'disabled="disabled"'; } ?> />
+	<label for="bp-enable-membership-requests"><?php esc_html_e( 'Allow visitors to request site membership. If enabled, an administrator must approve each new site membership request.', 'buddypress' ); ?></label>
+	<?php if ( bp_get_signup_allowed() ) : ?>
+		<p class="description"><?php esc_html_e( 'Public registration is currently enabled. If you wish to require approval for new memberships, disable public registration and enable the membership requests feature.', 'buddypress' ); ?></p>
+	<?php endif; ?>
+	<?php
+	/**
+	 * Fires after the output of the membership requests settings section.
+	 *
+	 * @since 10.0.0
+	 */
+	do_action( 'bp_admin_settings_after_membership_requests' );
+}
+
 /** XProfile ******************************************************************/
 
 /**
diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php
index 0e66f4cb7..fd938861f 100644
--- src/bp-core/bp-core-functions.php
+++ src/bp-core/bp-core-functions.php
@@ -3792,6 +3792,8 @@ function bp_core_replace_tokens_in_text( $text, $tokens ) {
  * Get a list of emails for populating the email post type.
  *
  * @since 2.5.1
+ * @since 10.0.0 Added members-membership-request and
+ *               members-membership-request-rejected email types.
  *
  * @return array
  */
@@ -3952,6 +3954,22 @@ function bp_email_get_schema() {
 			/* translators: do not remove {} brackets or translate its contents. */
 			'post_excerpt' => __( "{{inviter.name}} has invited you to join the site \"{{site.name}}\".\n\n{{usermessage}}\n\nTo accept your invitation, visit: {{{invite.accept_url}}}\n\nTo learn more about the site, visit: {{{site.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),
 		),
+		'members-membership-request' => array(
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_title'   => __( '{{requesting-user.user_login}} would like to join {{site.name}}', 'buddypress' ),
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_content' => __( "{{requesting-user.user_login}} would like to join the site: &quot;{{site.name}}&quot;.\n\n<a href=\"{{{manage.url}}}\">Manage the request</a>.", 'buddypress' ),
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_excerpt' => __( "{{requesting-user.user_login}} would like to join the site \"{{site.name}}\".\n\nTo manage the request, visit: {{{manage.url}}}.", 'buddypress' ),
+		),
+		'members-membership-request-rejected' => array(
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_title'   => __( 'Your request to join {{site.name}} has been declined', 'buddypress' ),
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_content' => __( "Sorry, your request to join the site &quot;{{site.name}}&quot; has been declined.", 'buddypress' ),
+			/* translators: do not remove {} brackets or translate its contents. */
+			'post_excerpt' => __( "Sorry, your request to join the site \"{{site.name}}\" has been declined.", 'buddypress' ),
+		),
 	) );
 }
 
@@ -4124,25 +4142,42 @@ function bp_email_get_type_schema( $field = 'description' ) {
 		),
 	);
 
+	$members_membership_request= array(
+		'description'	   => __( 'Someone has requested membership on this site.', 'buddypress' ),
+		'named_salutation' => true,
+		'unsubscribe'	   => array(
+			'meta_key' => 'notification_members_membership_request',
+			'message'  => __( 'You will no longer receive emails when people submit requests to join this site.', 'buddypress' ),
+		),
+	);
+
+	$members_membership_request_rejected= array(
+		'description'	   => __( 'A site membership request has been rejected.', 'buddypress' ),
+		'named_salutation' => false,
+		'unsubscribe'	   => false,
+	);
+
 	$types = array(
-		'activity-comment'                   => $activity_comment,
-		'activity-comment-author'            => $activity_comment_author,
-		'activity-at-message'                => $activity_at_message,
-		'groups-at-message'                  => $groups_at_message,
-		'core-user-registration'             => $core_user_registration,
-		'core-user-registration-with-blog'   => $core_user_registration_with_blog,
-		'friends-request'                    => $friends_request,
-		'friends-request-accepted'           => $friends_request_accepted,
-		'groups-details-updated'             => $groups_details_updated,
-		'groups-invitation'                  => $groups_invitation,
-		'groups-member-promoted'             => $groups_member_promoted,
-		'groups-membership-request'          => $groups_membership_request,
-		'messages-unread'                    => $messages_unread,
-		'settings-verify-email-change'       => $settings_verify_email_change,
-		'groups-membership-request-accepted' => $groups_membership_request_accepted,
-		'groups-membership-request-rejected' => $groups_membership_request_rejected,
-		'core-user-activation'               => $core_user_activation,
-		'bp-members-invitation'              => $members_invitation,
+		'activity-comment'                    => $activity_comment,
+		'activity-comment-author'             => $activity_comment_author,
+		'activity-at-message'                 => $activity_at_message,
+		'groups-at-message'                   => $groups_at_message,
+		'core-user-registration'              => $core_user_registration,
+		'core-user-registration-with-blog'    => $core_user_registration_with_blog,
+		'friends-request'                     => $friends_request,
+		'friends-request-accepted'            => $friends_request_accepted,
+		'groups-details-updated'              => $groups_details_updated,
+		'groups-invitation'                   => $groups_invitation,
+		'groups-member-promoted'              => $groups_member_promoted,
+		'groups-membership-request'           => $groups_membership_request,
+		'messages-unread'                     => $messages_unread,
+		'settings-verify-email-change'        => $settings_verify_email_change,
+		'groups-membership-request-accepted'  => $groups_membership_request_accepted,
+		'groups-membership-request-rejected'  => $groups_membership_request_rejected,
+		'core-user-activation'                => $core_user_activation,
+		'bp-members-invitation'               => $members_invitation,
+		'members-membership-request'          => $members_membership_request,
+		'members-membership-request-rejected' => $members_membership_request_rejected,
 	);
 
 	if ( $field !== 'all' ) {
diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php
index a88cd6800..9ef914ed9 100644
--- src/bp-core/bp-core-template.php
+++ src/bp-core/bp-core-template.php
@@ -3192,7 +3192,11 @@ function bp_get_title_parts( $seplocation = 'right' ) {
 
 	// Sign up page.
 	} elseif ( bp_is_register_page() ) {
-		$bp_title_parts = array( __( 'Create an Account', 'buddypress' ) );
+		if ( bp_get_membership_requests_required() ) {
+			$bp_title_parts = array( __( 'Request Membership', 'buddypress' ) );
+		} else {
+			$bp_title_parts = array( __( 'Create an Account', 'buddypress' ) );
+		}
 
 	// Activation page.
 	} elseif ( bp_is_activation_page() ) {
diff --git src/bp-core/bp-core-update.php src/bp-core/bp-core-update.php
index 03710213c..6468ace39 100644
--- src/bp-core/bp-core-update.php
+++ src/bp-core/bp-core-update.php
@@ -278,6 +278,12 @@ function bp_version_updater() {
 		if ( $raw_db_version < 12850 ) {
 			bp_update_to_8_0();
 		}
+
+		// Version 10.0.0.
+		if ( $raw_db_version < 13150 ) {
+			bp_update_to_10_0();
+		}
+
 	}
 
 	/* All done! *************************************************************/
@@ -704,6 +710,44 @@ function bp_core_get_8_0_upgrade_email_schema( $emails ) {
 	return $new_emails;
 }
 
+/**
+ * 10.0.0 update routine.
+ *
+ * - Install new BP Emails for membership requests.
+ *
+ * @since 10.0.0
+ */
+function bp_update_to_10_0() {
+
+	// Install membership request emails.
+	add_filter( 'bp_email_get_schema', 'bp_core_get_10_0_upgrade_email_schema' );
+
+	bp_core_install_emails();
+
+	remove_filter( 'bp_email_get_schema', 'bp_core_get_10_0_upgrade_email_schema' );
+}
+
+/**
+ * Select only the emails that need to be installed with version 10.0.
+ *
+ * @since 10.0.0
+ *
+ * @param array $emails The array of emails schema.
+ */
+function bp_core_get_10_0_upgrade_email_schema( $emails ) {
+	$new_emails = array();
+
+	if ( isset( $emails['members-membership-request'] ) ) {
+		$new_emails['members-membership-request'] = $emails['members-membership-request'];
+	}
+
+	if ( isset( $emails['members-membership-request-rejected'] ) ) {
+		$new_emails['members-membership-request-rejected'] = $emails['members-membership-request-rejected'];
+	}
+
+	return $new_emails;
+}
+
 /**
  * Updates the component field for new_members type.
  *
diff --git src/bp-core/classes/class-bp-admin.php src/bp-core/classes/class-bp-admin.php
index 9b7a87508..24d3678ee 100644
--- src/bp-core/classes/class-bp-admin.php
+++ src/bp-core/classes/class-bp-admin.php
@@ -482,6 +482,12 @@ class BP_Admin {
 			register_setting( 'buddypress', 'bp-enable-members-invitations', 'intval' );
 		}
 
+		// Membership requests.
+		if ( bp_is_active( 'members', 'membership_requests' ) ) {
+			add_settings_field( 'bp-enable-membership-requests', __( 'Membership Requests', 'buddypress' ), 'bp_admin_setting_callback_membership_requests', 'buddypress', 'bp_members' );
+			register_setting( 'buddypress', 'bp-enable-membership-requests', 'intval' );
+		}
+
 		/* XProfile Section **************************************************/
 
 		if ( bp_is_active( 'xprofile' ) ) {
diff --git src/bp-core/classes/class-bp-invitation-manager.php src/bp-core/classes/class-bp-invitation-manager.php
index d92a76b7a..718384e7d 100644
--- src/bp-core/classes/class-bp-invitation-manager.php
+++ src/bp-core/classes/class-bp-invitation-manager.php
@@ -227,7 +227,7 @@ abstract class BP_Invitation_Manager {
 	 * 	   @type int    $item_id ID associated with the invitation and class.
 	 * 	   @type int    $secondary_item_id secondary ID associated with the
 	 *			        invitation and class.
-	 * 	   @type string $type @TODO. < missing description.
+	 * 	   @type string $type    Type of record this is: 'invite' or 'request'.
 	 * 	   @type string $content Extra information provided by the requester
 	 *			        or inviter.
 	 * 	   @type string $date_modified Date the invitation was last modified.
diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
index 93fd7cafd..141c545fa 100644
--- src/bp-members/bp-members-functions.php
+++ src/bp-members/bp-members-functions.php
@@ -2388,24 +2388,18 @@ function bp_core_signup_send_validation_email( $user_id, $user_email, $key, $sal
 	bp_send_email( 'core-user-registration', $to, $args );
 
 	// Record that the activation email has been sent.
-	$signups = BP_Signup::get(
-		array(
-			'activation_key' => $key,
-		)
-	);
+	$signup = bp_members_get_signup_by( 'activation_key', $key );
 
-	if ( ! empty( $signups['signups'] ) ) {
-		foreach ( $signups['signups'] as $signup ) {
-			$meta = array(
-				'sent_date'  => current_time( 'mysql', true ),
-				'count_sent' => $signup->count_sent + 1
-			);
+	if ( $signup ) {
+		$meta = array(
+			'sent_date'  => current_time( 'mysql', true ),
+			'count_sent' => $signup->count_sent + 1
+		);
 
-			BP_Signup::update( array(
-				'signup_id' => $signup->id,
-				'meta'      => $meta,
-			) );
-		}
+		BP_Signup::update( array(
+			'signup_id' => $signup->id,
+			'meta'      => $meta,
+		) );
 	}
 }
 
@@ -2450,25 +2444,33 @@ function bp_core_signup_disable_inactive( $user = null, $username = '', $passwor
 	}
 
 	// Unactivated user account found!
-	// Set up the feedback message.
-	$signup_id = $signup['signups'][0]->signup_id;
+	/*
+	 * Don't allow users to resend their own activation email
+	 * when membership requests are enabled.
+	 */
+	if ( bp_get_membership_requests_required() ) {
+		return new WP_Error( 'bp_account_not_activated', __( '<strong>Error</strong>: Your membership request has not yet been approved.', 'buddypress' ) );
+	} else {
+		// Set up the feedback message.
+		$signup_id = $signup['signups'][0]->signup_id;
 
-	$resend_url_params = array(
-		'action' => 'bp-resend-activation',
-		'id'     => $signup_id,
-	);
+		$resend_url_params = array(
+			'action' => 'bp-resend-activation',
+			'id'     => $signup_id,
+		);
 
-	$resend_url = wp_nonce_url(
-		add_query_arg( $resend_url_params, wp_login_url() ),
-		'bp-resend-activation'
-	);
+		$resend_url = wp_nonce_url(
+			add_query_arg( $resend_url_params, wp_login_url() ),
+			'bp-resend-activation'
+		);
 
-	$resend_string = '<br /><br />';
+		$resend_string = '<br /><br />';
 
-	/* translators: %s: the activation url */
-	$resend_string .= sprintf( __( 'If you have not received an email yet, <a href="%s">click here to resend it</a>.', 'buddypress' ), esc_url( $resend_url ) );
+		/* translators: %s: the activation url */
+		$resend_string .= sprintf( __( 'If you have not received an email yet, <a href="%s">click here to resend it</a>.', 'buddypress' ), esc_url( $resend_url ) );
 
-	return new WP_Error( 'bp_account_not_activated', __( '<strong>Error</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) . $resend_string );
+		return new WP_Error( 'bp_account_not_activated', __( '<strong>Error</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) . $resend_string );
+	}
 }
 add_filter( 'authenticate', 'bp_core_signup_disable_inactive', 30, 3 );
 
@@ -3694,3 +3696,42 @@ function bp_get_members_invitation_from_request() {
 	 */
 	return apply_filters( 'bp_get_members_invitation_from_request', $invite );
 }
+
+/**
+ * Get WP_User object corresponding to a record in the signups table.
+ *
+ * @since 10.0.0
+ *
+ * @param string $field Which fields to search by. Possible values are
+ *                      activation_key, user_email, id.
+ * @param string $value Value to search by.
+ * @return bool|BP_Signup $signup Found signup, returns first found
+ *                                if more than one is found.
+ */
+function bp_members_get_signup_by( $field = 'activation_key', $value ) {
+	switch ( $field ) {
+		case 'activation_key':
+		case 'user_email':
+			$key = $field;
+			break;
+
+		case 'id':
+		default:
+			$key = 'include';
+			break;
+	}
+
+	$signups = BP_Signup::get(
+		array(
+			$key => $value,
+		)
+	);
+
+	if ( ! empty( $signups['signups'] ) ) {
+		$signup = current( $signups['signups'] );
+	} else {
+		$signup = false;
+	}
+
+	return $signup;
+}
diff --git src/bp-members/bp-members-invitations.php src/bp-members/bp-members-invitations.php
index 73f50e09b..7e95c791d 100644
--- src/bp-members/bp-members-invitations.php
+++ src/bp-members/bp-members-invitations.php
@@ -183,3 +183,39 @@ function bp_members_invitations_delete_optedout_invites( $optout ) {
 	);
 }
 add_action( 'bp_optout_after_save', 'bp_members_invitations_delete_optedout_invites' );
+
+/**
+ * If a user submits a site membership request, but there's a
+ * sent invitation to her, bypass the manual approval of the request.
+ *
+ * @since 10.0.0
+ *
+ * @param bool  $send    Whether or not this membership request should be approved
+ *                       immediately and the activation email sent.
+ *                       Default is `false` meaning that the request should be
+ *                       manually approved by a site admin.
+ * @param array $details The details of the request.
+ */
+function bp_members_invitations_maybe_bypass_request_approval( $send, $details ) {
+	if ( ! bp_get_members_invitations_allowed() ) {
+		return $send;
+	}
+
+	// We'll need the prospective user's email address.
+	if ( empty( $details['user_email'] ) ) {
+		return $send;
+	}
+
+	$invites = bp_members_invitations_get_invites(
+		array(
+			'invitee_email' => $details['user_email'],
+			'invite_sent'   => 'sent'
+		)
+	);
+	// If pending invitations exist, send the verification mail.
+	if ( $invites ) {
+		$send = true;
+	}
+	return $send;
+}
+add_filter( 'bp_members_membership_requests_bypass_manual_approval', 'bp_members_invitations_maybe_bypass_request_approval', 10, 2 );
diff --git src/bp-members/bp-members-membership-requests.php src/bp-members/bp-members-membership-requests.php
new file mode 100644
index 000000000..2f217db7b
--- /dev/null
+++ src/bp-members/bp-members-membership-requests.php
@@ -0,0 +1,365 @@
+<?php
+/**
+ * BuddyPress Membership Requests
+ *
+ * @package BuddyPress
+ * @subpackage MembersMembershipRequest
+ * @since 10.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * When a user creates a membership request,
+ * prevent the sending of the activation email so that
+ * the site admins can send it manually.
+ *
+ * @since 10.0.0
+ *
+ * @param bool   $send           Whether or not to send the activation key.
+ * @param int    $user_id        User ID to send activation key to.
+ * @param string $user_email     User email to send activation key to.
+ * @param string $activation_key Activation key to be sent.
+ * @param array  $usermeta       Miscellaneous metadata about the user (blog-specific
+ *                               signup data, xprofile data, etc).
+ * @return bool Whether or not to send the activation key.
+ */
+function bp_members_membership_requests_cancel_activation_email( $send, $user_id = 0, $user_email = '', $activation_key = '', $usermeta = array() ) {
+
+	$details = array(
+		'user_id'        => $user_id,
+		'user_email'     => $user_email,
+		'activation_key' => $activation_key,
+		'usermeta'       => $usermeta,
+	);
+
+	/**
+	 * Allow some membership requests to be approved immediately.
+	 * For example, you might want to approve all requests
+	 * coming from users with certain email address domains.
+	 * If `true` is returned the activation email will be sent to the user.
+	 *
+	 * @since 10.0.0
+	 *
+	 * @param bool  $send    Whether or not this membership request should be approved
+	 *                       immediately and the activation email sent.
+	 *                       Default is `false` meaning that the request should be
+	 *                       manually approved by a site admin.
+	 * @param array $details The details of the request.
+	 */
+	$send = apply_filters( 'bp_members_membership_requests_bypass_manual_approval', false, $details );
+
+	// If the registration process has been interrupted, this is a new membership request.
+	if ( ! $send ) {
+		$signup = bp_members_get_signup_by( 'activation_key', $activation_key );
+
+		/**
+		 * Fires when a site membership request has been created and is pending.
+		 *
+		 * @since 10.0.0
+		 *
+		 * @param BP_Signup $signup  The signup object that has been created.
+		 * @param array     $details The details of the request.
+		 */
+		do_action( 'bp_members_membership_request_submitted', $signup, $details );
+	}
+
+	return $send;
+}
+add_filter( 'bp_core_signup_send_activation_key', 'bp_members_membership_requests_cancel_activation_email', 10, 5 );
+
+
+/**
+ * Notifications
+ *********************************************************************/
+
+/**
+ * Notify site admins about a new membership request.
+ *
+ * @since 10.0.0
+ *
+ * @param BP_Signup $signup  The signup object that has been created.
+ */
+function bp_members_membership_requests_notify_site_admins( $signup ) {
+
+	// Notify all site admins so the request can be handled.
+	$admins_query = new WP_User_Query( array(
+		'role'   => 'administrator',
+		'fields' => 'ids'
+	) );
+	$admin_ids   = $admins_query->get_results();
+
+	foreach ( $admin_ids as $admin_id ) {
+		// Trigger a BuddyPress Notification.
+		if ( bp_is_active( 'notifications' ) ) {
+			bp_notifications_add_notification( array(
+				'user_id'           => $admin_id,
+				'item_id'           => $signup->signup_id,
+				'component_name'    => buddypress()->members->id,
+				'component_action'  => 'membership_request_submitted',
+				'date_notified'     => bp_core_current_time(),
+				'is_new'            => 1,
+			) );
+		}
+
+		// Bail if member opted out of receiving this email.
+		if ( 'no' === bp_get_user_meta( $admin_id, 'notification_members_membership_request', true ) ) {
+			return;
+		}
+
+		$unsubscribe_args = array(
+			'user_id'           => $admin_id,
+			'notification_type' => 'members-membership-request',
+		);
+		$manage_url = add_query_arg( array(
+			'mod_req'   => 1,
+			'page'      => 'bp-signups',
+			'signup_id' => $signup->signup_id,
+			'action'    => 'resend',
+		), bp_get_admin_url( 'users.php' ) );
+		$args  = array(
+			'tokens' => array(
+				'admin.id'                   => $admin_id,
+				'manage.url'                 => esc_url_raw( $manage_url ),
+				'requesting-user.user_login' => esc_html( $signup->user_login ),
+				'unsubscribe'                => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
+			),
+		);
+		bp_send_email( 'members-membership-request', (int) $admin_id, $args );
+	}
+
+}
+add_action( 'bp_members_membership_request_submitted', 'bp_members_membership_requests_notify_site_admins' );
+
+/**
+ * Send a message to the requesting user when his or her
+ * site membership request has been rejected.
+ *
+ * @since 10.0.0
+ *
+ * @param array $signup_ids Array of pending IDs to delete.
+ */
+function bp_members_membership_requests_send_rejection_mail( $signup_ids ) {
+	$signups = BP_Signup::get(
+		array(
+			'include' => $signup_ids,
+		)
+	);
+	if ( empty( $signups['signups'] ) ) {
+		return;
+	}
+	foreach ( $signups['signups'] as $signup ) {
+		if ( ! empty( $signup->user_email ) ) {
+			bp_send_email( 'members-membership-request-rejected', $signup->user_email );
+		}
+	}
+}
+add_action( 'bp_core_signup_before_delete', 'bp_members_membership_requests_send_rejection_mail' );
+
+/**
+ * When a request is approved, activated or deleted,
+ * delete the associated notifications.
+ *
+ * @since 10.0.0
+ *
+ * @param array $signup_ids Array of changing signup IDs.
+ */
+function bp_members_membership_requests_delete_notifications_on_change( $signup_ids ) {
+	foreach ( $signup_ids as $signup_id ) {
+		BP_Notifications_Notification::delete(
+			array(
+				'item_id'          => $signup_id,
+				'component_action' => 'membership_request_submitted',
+			)
+		);
+	}
+}
+add_action( 'bp_core_signup_after_resend',   'bp_members_membership_requests_delete_notifications_on_change' );
+add_action( 'bp_core_signup_after_activate', 'bp_members_membership_requests_delete_notifications_on_change' );
+add_action( 'bp_core_signup_after_delete',   'bp_members_membership_requests_delete_notifications_on_change' );
+
+/**
+ * In the Nouveau template pack, when membership requests are required,
+ * change registration form submit button label to "Submit Request".
+ *
+ * @since 10.0.0
+ *
+ * @return string $retval the HTML for the request membership link.
+ */
+function bp_members_membership_requests_filter_complete_signup_button( $buttons ) {
+
+	$buttons['register']['attributes']['value'] = __( 'Submit Request', 'buddypress' );
+	return $buttons;
+}
+add_filter( 'bp_nouveau_get_submit_button', 'bp_members_membership_requests_filter_complete_signup_button' );
+
+
+/**
+ * Administration: Change certain behavior and labels
+ * on the WP Admin > Users > Manage Signups screen.
+ *********************************************************************/
+
+/**
+ * Filter the actions available on the signups list table.
+ *
+ * @since 10.0.0
+ *
+ * @param array  $actions       Array of actions and corresponding links.
+ * @param object $signup_object The signup data object.
+ */
+function bp_members_membership_requests_filter_signup_row_actions( $actions, $signup_object ) {
+
+	// Rename the "email" resend option when membership requests are active.
+	$email_link = add_query_arg(
+		array(
+			'page'	    => 'bp-signups',
+			'signup_id' => $signup_object->id,
+			'action'    => 'resend',
+		),
+		bp_get_admin_url( 'users.php' )
+	);
+
+	$resend_label = ( 0 === $signup_object->count_sent ) ? __( 'Approve Request', 'buddypress' ) : __( 'Resend Approval', 'buddypress' );
+
+	$actions['resend'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $email_link ), $resend_label );
+
+	// Add a link to view profile info when membership requests and xprofile are active.
+	if ( bp_is_active( 'xprofile' ) ) {
+		$profile_link = add_query_arg(
+			array(
+				'page'	   => 'bp-signups#TB_inline',
+				'inlineId' => 'signup-info-modal-' . $signup_object->id,
+			),
+			bp_get_admin_url( 'users.php' )
+		);
+
+		$actions['profile'] = sprintf( '<a href="%1$s" class="thickbox">%2$s</a>', esc_url( $profile_link ), __( 'Profile Info', 'buddypress' ) );
+	}
+
+	return $actions;
+}
+add_filter( 'bp_members_ms_signup_row_actions', 'bp_members_membership_requests_filter_signup_row_actions', 10, 2 );
+
+/**
+ * Filter the bulk actions available on the signups list table.
+ *
+ * @since 10.0.0
+ *
+ * @param array  $actions       Array of actions and corresponding links.
+ */
+function bp_members_membership_requests_filter_signup_bulk_actions( $actions ) {
+	// Rename the "email" resend option when membership requests are active.
+	$actions['resend'] = _x( 'Approve', 'Pending signup action', 'buddypress' );
+	return $actions;
+}
+add_filter( 'bp_members_ms_signup_bulk_actions', 'bp_members_membership_requests_filter_signup_bulk_actions' );
+
+/**
+ * Filter the "Last Sent" column header on the pending users table.
+ *
+ * @since 10.0.0
+ *
+* @param array $value Array of columns to display.
+ */
+function bp_members_membership_requests_filter_signup_table_date_sent_header( $columns ) {
+	$columns['date_sent'] = __( 'Approved', 'buddypress' );
+	return $columns;
+}
+add_filter( 'bp_members_signup_columns', 'bp_members_membership_requests_filter_signup_table_date_sent_header' );
+add_filter( 'bp_members_ms_signup_columns', 'bp_members_membership_requests_filter_signup_table_date_sent_header' );
+
+/**
+ * Filter the "Last Sent" column message on the pending users table.
+ *
+ * @since 10.0.0
+ *
+ * @param string      $message "Not yet sent" message.
+ * @param object|null $signup  Signup object instance.
+ */
+function bp_members_membership_requests_filter_signup_table_unsent_message( $message, $signup ) {
+	if ( 0 === $signup->count_sent ) {
+		$message = __( 'Not yet approved', 'buddypress' );
+	}
+	return $message;
+}
+add_filter( 'bp_members_signup_date_sent_unsent_message', 'bp_members_membership_requests_filter_signup_table_unsent_message', 10, 2 );
+add_filter( 'bp_members_ms_signup_date_sent_unsent_message', 'bp_members_membership_requests_filter_signup_table_unsent_message', 10, 2 );
+
+/**
+ * Filter/add "Request Membership" links in the following locations:
+ * BP login widget
+ * sidebar register link
+ * WP Toolbar
+ * WP login form
+ *********************************************************************/
+
+/**
+ * Add "Request Membership" link to Widget login form.
+ *
+ * @since 10.0.0
+ *
+ * @return string $retval the HTML for the request membership link.
+ */
+function bp_members_membership_requests_add_link_to_widget_login_form() {
+	?>
+	<span class="bp-login-widget-request-membership-link"><a href="<?php echo esc_url( bp_get_signup_page() ); ?>"><?php esc_html_e( 'Request Membership', 'buddypress' ); ?></a></span>
+	<?php
+}
+add_action( 'bp_login_widget_form', 'bp_members_membership_requests_add_link_to_widget_login_form' );
+
+/**
+ * Filter the "Register" link from `wp_register()` as used in
+ * `sidebar.php` and the WP Core meta widget.
+ *
+ * @since 10.0.0
+ *
+ * @param string $link The HTML code for the link to the Registration or Admin page.
+ */
+function bp_members_membership_requests_filter_sidebar_register_link( $link ) {
+	// $link should be an empty string when public registration is disabled.
+	if ( ! is_user_logged_in() && empty( $link ) ) {
+		// @TODO: How can we know what before and after tags should be?
+		$link = '<li><a href="' . esc_url( wp_registration_url() ) . '">' . __( 'Request Membership' ) . '</a><li>';
+	}
+	return $link;
+}
+add_filter( 'register', 'bp_members_membership_requests_filter_sidebar_register_link' );
+
+/**
+ * Add a "Request Membership" link to the WP Toolbar.
+ * Priority 21 should place it just after the "Log In" link.
+ *
+ * @since 10.0.0
+ *
+ * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference
+ */
+function bp_members_membership_requests_add_toolbar_link( $wp_admin_bar ) {
+	if ( is_user_logged_in() ) {
+		return;
+	}
+
+	$args = array(
+		'id'    => 'bp-request-membership',
+		'title' => __( 'Request Membership' ),
+		'href'  => wp_registration_url(),
+		'meta'  => array(
+			'class' => 'buddypress-request-membership',
+			'title' => __( 'Request Membership' )
+		),
+	);
+	$wp_admin_bar->add_node( $args );
+}
+add_action( 'admin_bar_menu', 'bp_members_membership_requests_add_toolbar_link', 21 );
+
+/**
+ * Add a "Request Membership" link to the WP Login form.
+ *
+ * @since 10.0.0
+ *
+ * @param string $link HTML link to the home URL of the current site.
+ */
+function bp_members_membership_requests_add_link_wp_login( $link ) {
+	return $link . '&ensp;|&ensp;' . '<a href="' . esc_url( wp_registration_url() ) . '">' . __( 'Request Membership' ) . '</a>';
+}
+add_action( 'login_site_html_link', 'bp_members_membership_requests_add_link_wp_login' );
diff --git src/bp-members/bp-members-notifications.php src/bp-members/bp-members-notifications.php
index 93cee7b89..34c2677e9 100644
--- src/bp-members/bp-members-notifications.php
+++ src/bp-members/bp-members-notifications.php
@@ -61,6 +61,30 @@ function members_format_notifications( $action, $item_id, $secondary_item_id, $t
 				}
 			}
 			break;
+
+		case 'membership_request_submitted':
+			// $item_id is the id of the signup, not the user ID.
+			$signup = new BP_Signup( $item_id );
+
+			// Set up the string and the filter.
+			if ( (int) $total_items > 1 ) {
+				$link   = bp_get_notifications_permalink();
+				$amount = 'multiple';
+
+				$text = sprintf( __( '%d people have requested site membership.', 'buddypress' ), (int) $total_items );
+			} else {
+				$link   = add_query_arg( array(
+					'mod_req'   => 1,
+					'page'      => 'bp-signups',
+					'signup_id' => $item_id,
+					'action'    => 'resend',
+				), bp_get_admin_url( 'users.php' ) );
+				$amount = 'single';
+
+				/* translators: %s: new user name */
+				$text = sprintf( __( '%s has requested site membership.', 'buddypress' ),  esc_html( $signup->user_login ) );
+			}
+			break;
 	}
 
 	// Return either an HTML link or an array, depending on the requested format.
@@ -167,13 +191,35 @@ function bp_members_mark_read_accepted_invitation_notification() {
 			'is_new' => false,
 		),
 		array(
-			'user_id' => bp_loggedin_user_id(),
-			'item_id' => bp_displayed_user_id(),
+			'user_id'           => bp_loggedin_user_id(),
+			'item_id'           => bp_displayed_user_id(),
+			'component_action'  => 'accepted_invitation',
 		)
 	);
 }
 add_action( 'bp_screens', 'bp_members_mark_read_accepted_invitation_notification' );
 
+/**
+ * Mark new membership request notifications as read when user visits Manage BP Signups screen.
+ *
+ * @since 10.0.0
+ */
+function bp_members_mark_read_submitted_membership_request_notification() {
+	if ( ! wp_doing_ajax() && 'users_page_bp-signups' === get_current_screen()->base && ! empty( $_GET['mod_req'] ) && ! empty( $_GET['signup_id'] ) ) {
+		// Mark all notifications about this request as read.
+		BP_Notifications_Notification::update(
+			array(
+				'is_new' => false,
+			),
+			array(
+				'item_id'          => $_GET['signup_id'],
+				'component_action' => 'membership_request_submitted',
+			)
+		);
+	}
+}
+add_action( 'admin_footer', 'bp_members_mark_read_submitted_membership_request_notification' );
+
 /**
  * Add Members-related settings to the Settings > Notifications page.
  *
@@ -181,14 +227,10 @@ add_action( 'bp_screens', 'bp_members_mark_read_accepted_invitation_notification
  */
 function members_screen_notification_settings() {
 
-	// Bail early if invitations are not allowed--they are the only members notification so far.
-	if ( ! bp_get_members_invitations_allowed () ) {
+	// Bail early if invitations and requests are not allowed--they are the only members notification so far.
+	if ( ! bp_get_members_invitations_allowed() && ( ! bp_get_membership_requests_required() || ! user_can( bp_displayed_user_id(), 'bp_moderate' ) ) ) {
 		return;
 	}
-
-	if ( ! $allow_acceptance_emails = bp_get_user_meta( bp_displayed_user_id(), 'notification_members_invitation_accepted', true ) ) {
-		$allow_acceptance_emails = 'yes';
-	}
 	?>
 
 	<table class="notification-settings" id="members-notification-settings">
@@ -202,20 +244,47 @@ function members_screen_notification_settings() {
 		</thead>
 
 		<tbody>
-			<tr id="members-notification-settings-invitation_accepted">
-				<td></td>
-				<td><?php _ex( 'Someone accepts your membership invitation', 'Member settings on notification settings page', 'buddypress' ) ?></td>
-				<td class="yes"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-yes" value="yes" <?php checked( $allow_acceptance_emails, 'yes', true ) ?>/><label for="notification-members-invitation-accepted-yes" class="bp-screen-reader-text"><?php
-					/* translators: accessibility text */
-					_e( 'Yes, send email', 'buddypress' );
-				?></label></td>
-				<td class="no"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-no" value="no" <?php checked( $allow_acceptance_emails, 'no', true ) ?>/><label for="notification-members-invitation-accepted-no" class="bp-screen-reader-text"><?php
-					/* translators: accessibility text */
-					_e( 'No, do not send email', 'buddypress' );
-				?></label></td>
-			</tr>
 
 			<?php
+			if ( bp_get_members_invitations_allowed() ) :
+				if ( ! $allow_acceptance_emails = bp_get_user_meta( bp_displayed_user_id(), 'notification_members_invitation_accepted', true ) ) {
+					$allow_acceptance_emails = 'yes';
+				}
+				?>
+				<tr id="members-notification-settings-invitation_accepted">
+					<td></td>
+					<td><?php echo esc_html_x( 'Someone accepts your membership invitation', 'Member settings on notification settings page', 'buddypress' ); ?></td>
+					<td class="yes"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-yes" value="yes" <?php checked( $allow_acceptance_emails, 'yes', true ) ?>/><label for="notification-members-invitation-accepted-yes" class="bp-screen-reader-text"><?php
+						/* translators: accessibility text */
+						esc_html_e( 'Yes, send email', 'buddypress' );
+					?></label></td>
+					<td class="no"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-no" value="no" <?php checked( $allow_acceptance_emails, 'no', true ) ?>/><label for="notification-members-invitation-accepted-no" class="bp-screen-reader-text"><?php
+						/* translators: accessibility text */
+						esc_html_e( 'No, do not send email', 'buddypress' );
+					?></label></td>
+				</tr>
+				<?php
+			endif;
+
+			if ( bp_get_membership_requests_required() && user_can( bp_displayed_user_id(), 'bp_moderate' ) ) :
+				if ( ! $allow_request_emails = bp_get_user_meta( bp_displayed_user_id(), 'notification_members_membership_request', true ) ) {
+					$allow_request_emails = 'yes';
+				}
+				?>
+				<tr id="members-notification-settings-submitted_membership_request">
+					<td></td>
+					<td><?php echo esc_html_x( 'Someone has requested site membership', 'Member settings on notification settings page', 'buddypress' ) ?></td>
+					<td class="yes"><input type="radio" name="notifications[notification_members_membership_request]" id="notification-members-submitted_membership_request-yes" value="yes" <?php checked( $allow_request_emails, 'yes', true ) ?>/><label for="notification-members-submitted_membership_request-yes" class="bp-screen-reader-text"><?php
+						/* translators: accessibility text */
+						esc_html_e( 'Yes, send email', 'buddypress' );
+					?></label></td>
+					<td class="no"><input type="radio" name="notifications[notification_members_membership_request]" id="notification-members-submitted_membership_request-no" value="no" <?php checked( $allow_request_emails, 'no', true ) ?>/><label for="notification-members-submitted_membership_request-no" class="bp-screen-reader-text"><?php
+						/* translators: accessibility text */
+						esc_html_e( 'No, do not send email', 'buddypress' );
+					?></label></td>
+				</tr>
+				<?php
+			endif;
 
 			/**
 			 * Fires after the last table row on the members notification screen.
diff --git src/bp-members/bp-members-template.php src/bp-members/bp-members-template.php
index 10e6ef071..c9616ff9c 100644
--- src/bp-members/bp-members-template.php
+++ src/bp-members/bp-members-template.php
@@ -2921,6 +2921,35 @@ function bp_get_members_invitations_allowed() {
 	return apply_filters( 'bp_get_members_invitations_allowed', bp_is_active( 'members', 'invitations' ) && (bool) bp_get_option( 'bp-enable-members-invitations' ) );
 }
 
+/**
+ * Are membership requests required for joining this site?
+ *
+ * @since 10.0.0
+ *
+ * @param bool $context "raw" to fetch value from database,
+ *                      "site" to take "anyone can register" setting into account.
+ * @return bool
+ */
+function bp_get_membership_requests_required( $context = 'site' ) {
+	if ( 'raw' === $context ) {
+		$retval = bp_is_active( 'members', 'membership_requests' ) && (bool) bp_get_option( 'bp-enable-membership-requests' );
+	} else {
+		$retval = bp_is_active( 'members', 'membership_requests' ) && ! bp_get_signup_allowed() && (bool) bp_get_option( 'bp-enable-membership-requests' );
+	}
+
+	/**
+	 * Filters whether or not prospective members may submit network membership requests.
+	 *
+	 * @since 10.0.0
+	 *
+	 * @param bool $retval Whether or not membership requests are required.
+	 * @param bool $retval Whether this is the value stored in the database ('raw')
+	 *                     or whether the site's "anyone can register" setting is
+	 *                     being considered ('site' or anything else).
+	 */
+	return apply_filters( 'bp_get_membership_requests_required', $retval, $context );
+}
+
 /**
  * Should the system create and allow access
  * to the Register and Activate pages?
@@ -2930,7 +2959,7 @@ function bp_get_members_invitations_allowed() {
  * @return bool
  */
 function bp_allow_access_to_registration_pages() {
-	$retval = bp_get_signup_allowed() || bp_get_members_invitations_allowed();
+	$retval = bp_get_signup_allowed() || bp_get_members_invitations_allowed() || bp_get_membership_requests_required();
 
 	/**
 	 * Filters whether or not the system should create and allow access
diff --git src/bp-members/classes/class-bp-members-admin.php src/bp-members/classes/class-bp-members-admin.php
index 979847a18..7c352d0c1 100644
--- src/bp-members/classes/class-bp-members-admin.php
+++ src/bp-members/classes/class-bp-members-admin.php
@@ -514,10 +514,16 @@ class BP_Members_Admin {
 		// Only show sign-ups where they belong.
 		if ( ( ! bp_is_network_activated() && ! is_network_admin() ) || ( is_network_admin() && bp_is_network_activated() ) ) {
 
+			$signups_menu_label = __( 'Manage Signups',  'buddypress' );
+
+			if ( bp_get_membership_requests_required() ) {
+				$signups_menu_label = __( 'Manage Pending Memberships',  'buddypress' );
+			}
+
 			// Manage signups.
 			$hooks['signups'] = $this->signups_page = add_users_page(
-				__( 'Manage Signups',  'buddypress' ),
-				__( 'Manage Signups',  'buddypress' ),
+				$signups_menu_label,
+				$signups_menu_label,
 				$this->capability,
 				'bp-signups',
 				array( $this, 'signups_admin' )
@@ -1709,15 +1715,29 @@ class BP_Members_Admin {
 				'<p>' . __( 'Using the search form, you can find pending accounts more easily. The Username and Email fields will be included in the search.', 'buddypress' ) . '</p>'
 			) );
 
+			$signup_help_content = '<p>' . __( 'Hovering over a row in the pending accounts list will display action links that allow you to manage pending accounts. You can perform the following actions:', 'buddypress' ) . '</p>';
+
+			if ( bp_get_membership_requests_required() ) {
+				$signup_help_content .= '<ul><li>' . __( '"Activate" will activate the user immediately without requiring that they validate their email.', 'buddypress' ) .'</li>' .
+					'<li>' . __( '"Approve Request"/"Resend Apprival" takes you to the confirmation screen before being able to send the activation link to the desired pending request. You can only send the activation email once per day.', 'buddypress' ) . '</li>';
+
+				if ( bp_is_active( 'xprofile' ) ) {
+					$signup_help_content .=	'<li>' . __( '"Profile Info" will display extended profile information for the request.', 'buddypress' ) . '</li>';
+				}
+
+				$signup_help_content .= '<li>' . __( '"Delete" allows you to delete a pending account from your site. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>';
+			} else {
+				$signup_help_content .= '<ul><li>' . __( '"Email" takes you to the confirmation screen before being able to send the activation link to the desired pending account. You can only send the activation email once per day.', 'buddypress' ) . '</li>' .
+					'<li>' . __( '"Delete" allows you to delete a pending account from your site. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>';
+			}
+
+			$signup_help_content .= '<p>' . __( 'By clicking on a Username you will be able to activate a pending account from the confirmation screen.', 'buddypress' ) . '</p>' .
+				'<p>' . __( 'Bulk actions allow you to perform these 3 actions for the selected rows.', 'buddypress' ) . '</p>';
+
 			get_current_screen()->add_help_tab( array(
 				'id'      => 'bp-signups-actions',
 				'title'   => __( 'Actions', 'buddypress' ),
-				'content' =>
-				'<p>' . __( 'Hovering over a row in the pending accounts list will display action links that allow you to manage pending accounts. You can perform the following actions:', 'buddypress' ) . '</p>' .
-				'<ul><li>' . __( '"Email" takes you to the confirmation screen before being able to send the activation link to the desired pending account. You can only send the activation email once per day.', 'buddypress' ) . '</li>' .
-				'<li>' . __( '"Delete" allows you to delete a pending account from your site. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>' .
-				'<p>' . __( 'By clicking on a Username you will be able to activate a pending account from the confirmation screen.', 'buddypress' ) . '</p>' .
-				'<p>' . __( 'Bulk actions allow you to perform these 3 actions for the selected rows.', 'buddypress' ) . '</p>'
+				'content' => $signup_help_content
 			) );
 
 			// Help panel - sidebar links.
@@ -2204,7 +2224,7 @@ class BP_Members_Admin {
 		) );
 
 		$signups    = $signups_query['signups'];
-		$signup_ids = wp_list_pluck( $signups, 'signup_id' );
+		$signup_ids = wp_list_pluck( $signups, 'id' );
 
 		// Set up strings.
 		switch ( $action ) {
@@ -2227,13 +2247,24 @@ class BP_Members_Admin {
 				break;
 
 			case 'resend' :
-				$header_text = __( 'Resend Activation Emails', 'buddypress' );
-				if ( 1 == count( $signup_ids ) ) {
-					$helper_text = __( 'You are about to resend an activation email to the following account:', 'buddypress' );
+
+				if ( bp_get_membership_requests_required() ) {
+					$header_text = __( 'Approve Membership Requests', 'buddypress' );
+					if ( 1 === count( $signup_ids ) ) {
+						$helper_text = __( 'You are about to send an approval email to the following user:', 'buddypress' );
+					} else {
+						$helper_text = __( 'You are about to send approval emails to the following users:', 'buddypress' );
+					}
 				} else {
-					$helper_text = __( 'You are about to resend an activation email to the following accounts:', 'buddypress' );
+					$header_text = __( 'Resend Activation Emails', 'buddypress' );
+					if ( 1 === count( $signup_ids ) ) {
+						$helper_text = __( 'You are about to resend an activation email to the following account:', 'buddypress' );
+					} else {
+						$helper_text = __( 'You are about to resend an activation email to the following accounts:', 'buddypress' );
+					}
 				}
 				break;
+
 		}
 
 		// These arguments are added to all URLs.
@@ -2262,7 +2293,7 @@ class BP_Members_Admin {
 
 		// Prefetch registration field data.
 		$fdata = array();
-		if ( 'activate' === $action && bp_is_active( 'xprofile' ) ) {
+		if ( bp_is_active( 'xprofile' ) && ( 'activate' == $action || ( 'resend' == $action && bp_get_membership_requests_required() ) ) ) {
 			$field_groups = bp_xprofile_get_groups( array(
 				'exclude_fields'    => 1,
 				'update_meta_cache' => false,
@@ -2286,7 +2317,11 @@ class BP_Members_Admin {
 
 			<ol class="bp-signups-list">
 			<?php foreach ( $signups as $signup ) :
-				$last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent );
+				if ( $signup->count_sent > 0 ) {
+					$last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent );
+				} else {
+					$last_notified = __( 'Not yet notified', 'buddypress' );
+				}
 				$profile_field_ids = array();
 
 				// Get all xprofile field IDs except field 1.
@@ -2298,7 +2333,7 @@ class BP_Members_Admin {
 				<li>
 					<strong><?php echo esc_html( $signup->user_login ) ?></strong>
 
-					<?php if ( 'activate' == $action ) : ?>
+					<?php if ( 'activate' == $action || ( 'resend' == $action && bp_get_membership_requests_required() ) ) : ?>
 						<table class="wp-list-table widefat fixed striped">
 							<tbody>
 								<tr>
diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php
index 7bca5d8bb..135fb10ca 100644
--- src/bp-members/classes/class-bp-members-component.php
+++ src/bp-members/classes/class-bp-members-component.php
@@ -40,7 +40,7 @@ class BP_Members_Component extends BP_Component {
 			array(
 				'adminbar_myaccount_order' => 20,
 				'search_query_arg'         => 'members_search',
-				'features'                 => array( 'invitations' )
+				'features'                 => array( 'invitations', 'membership_requests' )
 			)
 		);
 	}
@@ -74,6 +74,10 @@ class BP_Members_Component extends BP_Component {
 			$includes[] = 'activity';
 		}
 
+		if ( bp_is_active( 'members', 'membership_requests' ) && (bool) bp_get_option( 'bp-enable-membership-requests' ) ) {
+			$includes[] = 'membership-requests';
+		}
+
 		// Include these only if in admin.
 		if ( is_admin() ) {
 			$includes[] = 'admin';
diff --git src/bp-members/classes/class-bp-members-list-table.php src/bp-members/classes/class-bp-members-list-table.php
index 8e7733b47..d9922b1fe 100644
--- src/bp-members/classes/class-bp-members-list-table.php
+++ src/bp-members/classes/class-bp-members-list-table.php
@@ -113,6 +113,11 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 
 		// Reset the screen id.
 		$this->screen->id = $reset_screen_id;
+
+		// Use thickbox to display the extended profile information.
+		if ( bp_is_active( 'xprofile' ) ) {
+			add_thickbox();
+		}
 	}
 
 	/**
@@ -138,14 +143,7 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 	 */
 	public function get_columns() {
 
-		/**
-		 * Filters the single site Members signup columns.
-		 *
-		 * @since 2.0.0
-		 *
-		 * @param array $value Array of columns to display.
-		 */
-		return apply_filters( 'bp_members_signup_columns', array(
+		$columns = array(
 			'cb'         => '<input type="checkbox" />',
 			'username'   => __( 'Username',    'buddypress' ),
 			'name'       => __( 'Name',        'buddypress' ),
@@ -153,7 +151,16 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 			'registered' => __( 'Registered',  'buddypress' ),
 			'date_sent'  => __( 'Last Sent',   'buddypress' ),
 			'count_sent' => __( 'Emails Sent', 'buddypress' )
-		) );
+		);
+
+		/**
+		 * Filters the single site Members signup columns.
+		 *
+		 * @since 2.0.0
+		 *
+		 * @param array $value Array of columns to display.
+		 */
+		return apply_filters( 'bp_members_signup_columns', $columns );
 	}
 
 	/**
@@ -171,7 +178,14 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 			$actions['delete'] = __( 'Delete', 'buddypress' );
 		}
 
-		return $actions;
+		/**
+		 * Filters the bulk actions for signups.
+		 *
+		 * @since 10.0.0
+		 *
+		 * @param array $actions Array of actions and corresponding labels.
+		 */
+		return apply_filters( 'bp_members_ms_signup_bulk_actions', $actions );
 	}
 
 	/**
@@ -183,7 +197,7 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 	 */
 	public function no_items() {
 
-		if ( bp_get_signup_allowed() ) {
+		if ( bp_get_signup_allowed() || bp_get_membership_requests_required() ) {
 			esc_html_e( 'No pending accounts found.', 'buddypress' );
 		} else {
 			$link = false;
@@ -342,6 +356,53 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 	 */
 	public function column_name( $signup_object = null ) {
 		echo esc_html( $signup_object->user_name );
+
+		// Insert the extended profile modal content required by thickbox.
+		if ( ! bp_is_active( 'xprofile' ) ) {
+			return;
+		}
+
+		$profile_field_ids = array();
+
+		// Prefetch registration field data.
+		$fdata = array();
+		$field_groups = bp_xprofile_get_groups( array(
+			'exclude_fields'    => 1,
+			'update_meta_cache' => false,
+			'fetch_fields'      => true,
+		) );
+
+		foreach( $field_groups as $fg ) {
+			foreach( $fg->fields as $f ) {
+				$fdata[ $f->id ] = $f->name;
+			}
+		}
+
+		// Get all xprofile field IDs except field 1.
+		if ( ! empty( $signup_object->meta['profile_field_ids'] ) ) {
+			$profile_field_ids = array_flip( explode( ',', $signup_object->meta['profile_field_ids'] ) );
+			unset( $profile_field_ids[1] );
+		}
+		?>
+		<div id="signup-info-modal-<?php echo $signup_object->id; ?>" style="display:none;">
+			<h1><?php printf( esc_html__( '%1$s (%2$s)', 'buddypress' ), esc_html( $signup_object->user_name ), esc_html( $signup_object->user_email ) ); ?></h1>
+			<h2><?php echo esc_html__( 'Extended Profile Information', 'buddypress' ); ?></h2>
+
+			<table class="signup-profile-data-drawer wp-list-table widefat fixed striped">
+				<?php if ( 1 <= count( $profile_field_ids ) ): foreach ( $profile_field_ids as $pid => $noop ) :
+					$field_value = isset( $signup_object->meta[ "field_{$pid}" ] ) ? $signup_object->meta[ "field_{$pid}" ] : ''; ?>
+					<tr>
+						<td class="column-fields"><?php echo esc_html( $fdata[ $pid ] ); ?></td>
+						<td><?php echo $this->format_xprofile_field_for_display( $field_value ); ?></td>
+					</tr>
+				<?php endforeach; else:  ?>
+					<tr>
+						<td><?php esc_html_e( 'There is no additional information to display.', 'buddypress' ); ?></td>
+					</tr>
+				<?php endif; ?>
+			</table>
+		</div>
+		<?php
 	}
 
 	/**
@@ -374,11 +435,28 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 	 * @param object|null $signup_object The signup data object.
 	 */
 	public function column_date_sent( $signup_object = null ) {
-		echo mysql2date( 'Y/m/d', $signup_object->date_sent );
+		if ( $signup_object->count_sent > 0 ) {
+			echo mysql2date( 'Y/m/d', $signup_object->date_sent );
+		} else {
+			$message = __( 'Not yet notified', 'buddypress' );
+
+			/**
+			 * Filters the "not yet sent" message for "Last Sent"
+			 * column in Manage Signups list table.
+			 *
+			 * @since 10.0.0
+			 *
+			 * @param string      $message       "Not yet sent" message.
+			 * @param object|null $signup_object Signup object instance.
+			 */
+			$message = apply_filters( 'bp_members_signup_date_sent_unsent_message', $message, $signup_object );
+
+			echo esc_html( $message );
+		}
 	}
 
 	/**
-	 * Display number of time an activation email has been sent.
+	 * Display number of times an activation email has been sent.
 	 *
 	 * @since 2.0.0
 	 *
@@ -409,4 +487,27 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 		 */
 		return apply_filters( 'bp_members_signup_custom_column', '', $column_name, $signup_object );
 	}
+
+	/**
+	 * Formats a signup's xprofile field data for display.
+	 *
+	 * Operates recursively on arrays, which are then imploded with commas.
+	 *
+	 * @since 10.0.0
+	 * @see BP_Members_Admin::format_xprofile_field_for_display()
+	 *
+	 * @param string|array $value Field value.
+	 * @return string
+	 */
+	protected function format_xprofile_field_for_display( $value ) {
+		if ( is_array( $value ) ) {
+			$value = array_map( array( $this, 'format_xprofile_field_for_display' ), $value );
+			$value = implode( ', ', $value );
+		} else {
+			$value = stripslashes( $value );
+			$value = esc_html( $value );
+		}
+
+		return $value;
+	}
 }
diff --git src/bp-members/classes/class-bp-members-ms-list-table.php src/bp-members/classes/class-bp-members-ms-list-table.php
index b8e86f906..662146c78 100644
--- src/bp-members/classes/class-bp-members-ms-list-table.php
+++ src/bp-members/classes/class-bp-members-ms-list-table.php
@@ -114,6 +114,11 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 
 		// Reset the screen id.
 		$this->screen->id = $reset_screen_id;
+
+		// Use thickbox to display the extended profile information.
+		if ( bp_is_active( 'xprofile' ) ) {
+			add_thickbox();
+		}
 	}
 
 	/**
@@ -125,14 +130,7 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 	 */
 	public function get_columns() {
 
-		/**
-		 * Filters the multisite Members signup columns.
-		 *
-		 * @since 2.0.0
-		 *
-		 * @param array $value Array of columns to display.
-		 */
-		return apply_filters( 'bp_members_ms_signup_columns', array(
+		$columns = array(
 			'cb'         => '<input type="checkbox" />',
 			'username'   => __( 'Username',    'buddypress' ),
 			'name'       => __( 'Name',        'buddypress' ),
@@ -140,7 +138,16 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 			'registered' => __( 'Registered',  'buddypress' ),
 			'date_sent'  => __( 'Last Sent',   'buddypress' ),
 			'count_sent' => __( 'Emails Sent', 'buddypress' )
-		) );
+		);
+
+		/**
+		 * Filters the multisite Members signup columns.
+		 *
+		 * @since 2.0.0
+		 *
+		 * @param array $value Array of columns to display.
+		 */
+		return apply_filters( 'bp_members_ms_signup_columns', $columns );
 	}
 
 	/**
@@ -158,7 +165,14 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 			$actions['delete'] = __( 'Delete', 'buddypress' );
 		}
 
-		return $actions;
+		/**
+		 * Filters the bulk actions for signups.
+		 *
+		 * @since 10.0.0
+		 *
+		 * @param array $actions Array of actions and corresponding labels.
+		 */
+		return apply_filters( 'bp_members_ms_signup_bulk_actions', $actions );
 	}
 
 	/**
@@ -169,7 +183,7 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 	 * @since 2.0.0
 	 */
 	public function no_items() {
-		if ( bp_get_signup_allowed() ) {
+		if ( bp_get_signup_allowed() || bp_get_membership_requests_required() ) {
 			esc_html_e( 'No pending accounts found.', 'buddypress' );
 		} else {
 			$link = false;
@@ -328,6 +342,53 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 	 */
 	public function column_name( $signup_object = null ) {
 		echo esc_html( $signup_object->user_name );
+
+		// Insert the extended profile modal content required by thickbox.
+		if ( ! bp_is_active( 'xprofile' ) ) {
+			return;
+		}
+
+		$profile_field_ids = array();
+
+		// Prefetch registration field data.
+		$fdata = array();
+		$field_groups = bp_xprofile_get_groups( array(
+			'exclude_fields'    => 1,
+			'update_meta_cache' => false,
+			'fetch_fields'      => true,
+		) );
+
+		foreach( $field_groups as $fg ) {
+			foreach( $fg->fields as $f ) {
+				$fdata[ $f->id ] = $f->name;
+			}
+		}
+
+		// Get all xprofile field IDs except field 1.
+		if ( ! empty( $signup_object->meta['profile_field_ids'] ) ) {
+			$profile_field_ids = array_flip( explode( ',', $signup_object->meta['profile_field_ids'] ) );
+			unset( $profile_field_ids[1] );
+		}
+		?>
+		<div id="signup-info-modal-<?php echo $signup_object->id; ?>" style="display:none;">
+			<h1><?php printf( esc_html__( '%1$s (%2$s)', 'buddypress' ), esc_html( $signup_object->user_name ), esc_html( $signup_object->user_email ) ); ?></h1>
+			<h2><?php echo esc_html__( 'Extended Profile Information', 'buddypress' ); ?></h2>
+
+			<table class="signup-profile-data-drawer wp-list-table widefat fixed striped">
+				<?php if ( 1 <= count( $profile_field_ids ) ): foreach ( $profile_field_ids as $pid => $noop ) :
+					$field_value = isset( $signup_object->meta[ "field_{$pid}" ] ) ? $signup_object->meta[ "field_{$pid}" ] : ''; ?>
+					<tr>
+						<td class="column-fields"><?php echo esc_html( $fdata[ $pid ] ); ?></td>
+						<td><?php echo $this->format_xprofile_field_for_display( $field_value ); ?></td>
+					</tr>
+				<?php endforeach;else:  ?>
+					<tr>
+						<td><?php esc_html_e( 'There is no additional information to display.', 'buddypress' ); ?></td>
+					</tr>
+				<?php endif; ?>
+			</table>
+		</div>
+		<?php
 	}
 
 	/**
@@ -376,7 +437,24 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 			$date = 'Y/m/d \<\b\r \/\> g:i:s a';
 		}
 
-		echo mysql2date( $date, $signup_object->date_sent );
+		if ( $signup_object->count_sent > 0 ) {
+			echo mysql2date( $date, $signup_object->date_sent );
+		} else {
+			$message = __( 'Not yet notified', 'buddypress' );
+
+			/**
+			 * Filters the "not yet sent" message for "Last Sent"
+			 * column in Manage Signups list table.
+			 *
+			 * @since 10.0.0
+			 *
+			 * @param string      $message       "Not yet sent" message.
+			 * @param object|null $signup_object Signup object instance.
+			 */
+			$message = apply_filters( 'bp_members_ms_signup_date_sent_unsent_message', $message, $signup_object );
+
+			echo esc_html( $message );
+		}
 	}
 
 	/**
@@ -411,4 +489,27 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 		 */
 		return apply_filters( 'bp_members_ms_signup_custom_column', '', $column_name, $signup_object );
 	}
+
+	/**
+	 * Formats a signup's xprofile field data for display.
+	 *
+	 * Operates recursively on arrays, which are then imploded with commas.
+	 *
+	 * @since 10.0.0
+	 * @see BP_Members_Admin::format_xprofile_field_for_display()
+	 *
+	 * @param string|array $value Field value.
+	 * @return string
+	 */
+	protected function format_xprofile_field_for_display( $value ) {
+		if ( is_array( $value ) ) {
+			$value = array_map( array( $this, 'format_xprofile_field_for_display' ), $value );
+			$value = implode( ', ', $value );
+		} else {
+			$value = stripslashes( $value );
+			$value = esc_html( $value );
+		}
+
+		return $value;
+	}
 }
diff --git src/bp-members/classes/class-bp-registration-theme-compat.php src/bp-members/classes/class-bp-registration-theme-compat.php
index 6a942a58b..f4e3e6855 100644
--- src/bp-members/classes/class-bp-registration-theme-compat.php
+++ src/bp-members/classes/class-bp-registration-theme-compat.php
@@ -97,10 +97,18 @@ class BP_Registration_Theme_Compat {
 	public function dummy_post() {
 		// Registration page.
 		if ( bp_is_register_page() ) {
-			$title = __( 'Create an Account', 'buddypress' );
+			if ( bp_get_membership_requests_required() ) {
+				$title = __( 'Request Membership', 'buddypress' );
+			} else {
+				$title = __( 'Create an Account', 'buddypress' );
+			}
 
 			if ( 'completed-confirmation' == bp_get_current_signup_step() ) {
-				$title = __( 'Check Your Email To Activate Your Account!', 'buddypress' );
+				if ( bp_get_membership_requests_required() ) {
+					$title = __( 'Your Membership Request has been submitted.', 'buddypress' );
+				} else {
+					$title = __( 'Check Your Email To Activate Your Account!', 'buddypress' );
+				}
 			}
 
 		// Activation page.
diff --git src/bp-members/classes/class-bp-signup.php src/bp-members/classes/class-bp-signup.php
index 9de2af9fe..76b2022d0 100644
--- src/bp-members/classes/class-bp-signup.php
+++ src/bp-members/classes/class-bp-signup.php
@@ -214,6 +214,17 @@ class BP_Signup {
 			$this->date_sent = $signup->registered;
 		}
 
+		// How many times has the activation email been sent?
+		if ( isset( $this->meta['count_sent'] ) ) {
+			$this->count_sent = absint( $this->meta['count_sent'] );
+		} else {
+			/**
+			 * Meta will not be set if this is a pre-10.0 signup.
+			 * In this case, we assume that the count is 1.
+			 */
+			$this->count_sent = 1;
+		}
+
 		/**
 		 * Calculate a diff between now & last time
 		 * an activation link has been resent.
@@ -226,14 +237,8 @@ class BP_Signup {
 		 * Set a boolean to track whether an activation link
 		 * was sent in the last day.
 		 */
-		$this->recently_sent = ( $diff < 1 * DAY_IN_SECONDS );
+		$this->recently_sent = $this->count_sent && ( $diff < 1 * DAY_IN_SECONDS );
 
-		// How many times has the activation email been sent?
-		if ( isset( $this->meta['count_sent'] ) ) {
-			$this->count_sent = absint( $this->meta['count_sent'] );
-		} else {
-			$this->count_sent = 0;
-		}
 	}
 
 	/** Static Methods *******************************************************/
diff --git src/bp-members/screens/register.php src/bp-members/screens/register.php
index 77929c442..40dd280dc 100644
--- src/bp-members/screens/register.php
+++ src/bp-members/screens/register.php
@@ -61,7 +61,9 @@ function bp_core_screen_signup() {
 		}
 	}
 
-	if ( ! bp_get_signup_allowed() && ! $active_invite ) {
+	$requests_enabled = bp_get_membership_requests_required();
+
+	if ( ! bp_get_signup_allowed() && ! $active_invite && ! $requests_enabled ) {
 		$bp->signup->step = 'registration-disabled';
 		// If the signup page is submitted, validate and save.
 	} elseif ( isset( $_POST['signup_submit'] ) && bp_verify_nonce_request( 'bp_new_signup' ) ) {
diff --git src/bp-templates/bp-legacy/buddypress/members/register.php src/bp-templates/bp-legacy/buddypress/members/register.php
index d263470f2..dd6365b45 100644
--- src/bp-templates/bp-legacy/buddypress/members/register.php
+++ src/bp-templates/bp-legacy/buddypress/members/register.php
@@ -351,10 +351,17 @@
 			 *
 			 * @since 1.1.0
 			 */
-			do_action( 'bp_before_registration_submit_buttons' ); ?>
+			do_action( 'bp_before_registration_submit_buttons' );
+
+			if ( bp_get_membership_requests_required() ) {
+				$button_text = __( 'Submit Request', 'buddypress' );
+			} else {
+				$button_text = __( 'Complete Sign Up', 'buddypress' );
+			}
+			?>
 
 			<div class="submit">
-				<input type="submit" name="signup_submit" id="signup_submit" value="<?php esc_attr_e( 'Complete Sign Up', 'buddypress' ); ?>" />
+				<input type="submit" name="signup_submit" id="signup_submit" value="<?php echo esc_attr( $button_text ); ?>" />
 			</div>
 
 			<?php
@@ -390,7 +397,9 @@
 			do_action( 'bp_before_registration_confirmed' ); ?>
 
 			<div id="template-notices" role="alert" aria-atomic="true">
-				<?php if ( bp_registration_needs_activation() ) : ?>
+				<?php if ( bp_get_membership_requests_required() ) : ?>
+					<p><?php _e( 'You have successfully submitted your membership request! Our site moderators will review your submission and send you an activation email if your request is approved.', 'buddypress' ); ?></p>
+				<?php elseif ( bp_registration_needs_activation() ) : ?>
 					<p><?php _e( 'You have successfully created your account! To begin using this site you will need to activate your account via the email we have just sent to your address.', 'buddypress' ); ?></p>
 				<?php else : ?>
 					<p><?php _e( 'You have successfully created your account! Please log in using the username and password you have just created.', 'buddypress' ); ?></p>
diff --git src/bp-templates/bp-nouveau/includes/functions.php src/bp-templates/bp-nouveau/includes/functions.php
index 8f36ac097..3e6bb22b1 100644
--- src/bp-templates/bp-nouveau/includes/functions.php
+++ src/bp-templates/bp-nouveau/includes/functions.php
@@ -1122,7 +1122,9 @@ function bp_nouveau_get_user_feedback( $feedback_id = '' ) {
 	/*
 	 * Adjust some messages to the context.
 	 */
-	if ( 'completed-confirmation' === $feedback_id && bp_registration_needs_activation() ) {
+	if ( 'completed-confirmation' === $feedback_id && bp_get_membership_requests_required() ) {
+		$feedback_messages['completed-confirmation']['message'] = __( 'You have successfully submitted your membership request! Our site moderators will review your submission and send you an activation email if your request is approved.', 'buddypress' );
+	} elseif ( 'completed-confirmation' === $feedback_id && bp_registration_needs_activation() ) {
 		$feedback_messages['completed-confirmation']['message'] = __( 'You have successfully created your account! To begin using this site you will need to activate your account via the email we have just sent to your address.', 'buddypress' );
 	} elseif ( 'member-notifications-none' === $feedback_id ) {
 		$is_myprofile = bp_is_my_profile();
diff --git src/class-buddypress.php src/class-buddypress.php
index 981ae06a1..41be07434 100644
--- src/class-buddypress.php
+++ src/class-buddypress.php
@@ -350,7 +350,7 @@ class BuddyPress {
 		/** Versions */
 
 		$this->version    = '10.0.0-alpha';
-		$this->db_version = 12850;
+		$this->db_version = 13150;
 
 		/** Loading */
 
