diff --git src/bp-core/admin/bp-core-admin-settings.php src/bp-core/admin/bp-core-admin-settings.php
index b37b914ff..a7e93c098 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' ) ); ?> />
+	<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 3dbc32f11..b140fbf6d 100644
--- src/bp-core/bp-core-functions.php
+++ src/bp-core/bp-core-functions.php
@@ -3800,6 +3800,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
  */
@@ -3960,6 +3962,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' ),
+		),
 	) );
 }
 
@@ -4132,25 +4150,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 efb251957..87a16b7a6 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..d7e0d5b5b 100644
--- src/bp-core/bp-core-update.php
+++ src/bp-core/bp-core-update.php
@@ -704,6 +704,23 @@ function bp_core_get_8_0_upgrade_email_schema( $emails ) {
 	return $new_emails;
 }
 
+/**
+ * 10.0.0 update routine.
+ *
+ * - Explicitly set all signups to count_sent = 1 & sent_date to registered_date
+ * - **Create the new BP Emails**.
+ *
+ * @since 10.0.0
+ */
+function bp_update_to_10_0() {
+
+	// @TODO: Explicitly set all signups to count_sent = 1 & sent_date to registered_date
+	// Is there any way to update that meta in bulk? I think it will have to be one at a time.
+
+	// Do we need this upgrade routine?
+	// Could we just assume if count_sent or sent_date defaults to 1 and to the registered_date into the PHP Code?
+}
+
 /**
  * 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 ee80328cc..ebe217a22 100644
--- src/bp-core/classes/class-bp-admin.php
+++ src/bp-core/classes/class-bp-admin.php
@@ -417,6 +417,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-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..cc7bd0da3
--- /dev/null
+++ src/bp-members/bp-members-membership-requests.php
@@ -0,0 +1,355 @@
+<?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 );
+
+	return $actions;
+	//@TODO add help to manage signups screen:
+	// Activate will activate the user immediately without requiring that they validate their email.
+	// Approve Request will send the user an activation email, so they will still need to take action. This also will check that the user's email address is valid.
+}
+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-membership-requests.php.rej src/bp-members/bp-members-membership-requests.php.rej
new file mode 100644
index 000000000..133644cdd
--- /dev/null
+++ src/bp-members/bp-members-membership-requests.php.rej
@@ -0,0 +1,177 @@
+***************
+*** 0 ****
+--- 1,174 ----
++ <?php
++ /**
++  * BuddyPress Membership Requests
++  *
++  * @package BuddyPress
++  * @subpackage MembersMembershipRequest
++  * @since 10.0.0
++  */
++ 
++ // Exit if accessed directly.
++ defined( 'ABSPATH' ) || exit;
++ 
++ /**
++  * When a user creates a network membership request,
++  * prevent the sending of the activation email so that
++  * the site admins can send it later.
++  *
++  * @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() ) {
++ 
++ 	if ( bp_get_membership_requests_required() ) {
++ 		$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 );
++ 
++ 
++ /**
++  * 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 ) {
++ 	// Why not just using get_option( 'admin_email' ) ?
++ 	$admin_ids = get_users(
++ 		array(
++ 			'fields' => 'ids',
++ 			'role'   => 'administrator',
++ 		)
++ 	);
++ 
++ 	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' );
++ 
++ /**
++  * 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() {
++ 	if ( ! bp_get_membership_requests_required() ) {
++ 		return;
++ 	}
++ 	?>
++ 	<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' );
++ 
++ /**
++  * 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 ) {
++ 	if ( bp_get_membership_requests_required() ) {
++ 		$buttons['register']['attributes']['value'] = __( 'Submit Request', 'buddypress' );
++ 	}
++ 
++ 	return $buttons;
++ }
++ add_filter( 'bp_nouveau_get_submit_button', 'bp_members_membership_requests_filter_complete_signup_button' );
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 39cfd6e65..0cf357023 100644
--- src/bp-members/bp-members-template.php
+++ src/bp-members/bp-members-template.php
@@ -2925,6 +2925,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?
@@ -2934,7 +2963,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 19ec1946b..c2e5fc9cf 100644
--- src/bp-members/classes/class-bp-members-admin.php
+++ src/bp-members/classes/class-bp-members-admin.php
@@ -501,10 +501,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' )
@@ -2186,7 +2192,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 ) {
@@ -2209,13 +2215,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.
@@ -2244,7 +2261,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,
@@ -2268,7 +2285,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.
@@ -2280,7 +2301,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 432e3ecce..e247fa54b 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..feb9b4668 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,29 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 			'registered' => __( 'Registered',  'buddypress' ),
 			'date_sent'  => __( 'Last Sent',   'buddypress' ),
 			'count_sent' => __( 'Emails Sent', 'buddypress' )
-		) );
+		);
+
+		if ( bp_is_active( 'xprofile' ) ) {
+			$profile_entry = array(
+				'extended_profile' => __( 'Profile Info', 'buddypress' )
+			);
+			$position = 4;
+			$columns = array_merge(
+				array_slice( $columns, 0, $position, true ),
+				$profile_entry,
+				array_slice( $columns, $position, count( $columns ) - 1, true )
+			);
+
+		}
+
+		/**
+		 * 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 +191,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 +210,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;
@@ -374,11 +401,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
 	 *
@@ -388,6 +432,60 @@ class BP_Members_List_Table extends WP_Users_List_Table {
 		echo absint( $signup_object->count_sent );
 	}
 
+	/**
+	 * Display link to open a modal to show user's
+	 * submitted extended profile information.
+	 *
+	 * @since 10.0.0
+	 *
+	 * @param object|null $signup_object The signup data object.
+	 */
+	public function column_extended_profile( $signup_object = null  ) {
+	   $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] );
+		}
+		?>
+		<a href="#TB_inline?&inlineId=signup-info-modal-<?php echo $signup_object->id; ?>" class="thickbox"><?php echo esc_html__( 'View', 'buddypress' ); ?></a>
+
+		<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 are no additional information to display.', 'buddypress' ); ?></td>
+					</tr>
+				<?php endif; ?>
+			</table>
+		</div>
+		<?php
+	}
+
 	/**
 	 * Allow plugins to add their custom column.
 	 *
@@ -409,4 +507,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..918748378 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,29 @@ 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' )
-		) );
+		);
+
+		if ( bp_is_active( 'xprofile' ) ) {
+			$profile_entry = array(
+				'extended_profile' => __( 'Profile Info', 'buddypress' )
+			);
+			$position = 4;
+			$columns = array_merge(
+				array_slice( $columns, 0, $position, true ),
+				$profile_entry,
+				array_slice( $columns, $position, count( $columns ) - 1, true )
+			);
+
+		}
+
+		/**
+		 * 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 +178,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 +196,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;
@@ -376,7 +403,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 );
+		}
 	}
 
 	/**
@@ -390,6 +434,60 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
 		echo absint( $signup_object->count_sent );
 	}
 
+		/**
+	 * Display link to open a modal to show user's
+	 * submitted extended profile information.
+	 *
+	 * @since 10.0.0
+	 *
+	 * @param object|null $signup_object The signup data object.
+	 */
+	public function column_extended_profile( $signup_object = null  ) {
+	   $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] );
+		}
+		?>
+		<a href="#TB_inline?&inlineId=signup-info-modal-<?php echo $signup_object->id; ?>" class="thickbox"><?php echo esc_html__( 'View', 'buddypress' ); ?></a>
+
+		<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 are no additional information to display.', 'buddypress' ); ?></td>
+					</tr>
+				<?php endif; ?>
+			</table>
+		</div>
+		<?php
+	}
+
 	/**
 	 * Allow plugins to add their custom column.
 	 *
@@ -411,4 +509,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..c436c7262 100644
--- src/bp-members/classes/class-bp-signup.php
+++ src/bp-members/classes/class-bp-signup.php
@@ -214,6 +214,13 @@ 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 {
+			$this->count_sent = 0;
+		}
+
 		/**
 		 * Calculate a diff between now & last time
 		 * an activation link has been resent.
@@ -226,14 +233,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 3d85eace9..5faa6b0f9 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();
