diff --git a/ee/app/controllers/ee/admin/application_settings_controller.rb b/ee/app/controllers/ee/admin/application_settings_controller.rb
index 813c830b8494edcc5770c7b4b75640de5806512e..baae7810e9d305bead6d134f8c7aeb19cb42984c 100644
--- a/ee/app/controllers/ee/admin/application_settings_controller.rb
+++ b/ee/app/controllers/ee/admin/application_settings_controller.rb
@@ -176,10 +176,6 @@ def visible_application_setting_attributes
           attrs << :make_profile_private
         end
 
-        if promotion_management_available?
-          attrs << :enable_member_promotion_management
-        end
-
         attrs << :new_user_signups_cap
         attrs << :namespace_storage_forks_cost_factor
 
diff --git a/ee/app/helpers/ee/application_settings_helper.rb b/ee/app/helpers/ee/application_settings_helper.rb
index edba8b35bc237f39b5cfcbeaeadf4dfc7723df0f..4f0903f7b43a5bbee9fc8e6dbf32055a863a6957 100644
--- a/ee/app/helpers/ee/application_settings_helper.rb
+++ b/ee/app/helpers/ee/application_settings_helper.rb
@@ -87,6 +87,7 @@ def visible_attributes
         :scan_execution_policies_action_limit
       ].tap do |settings|
         settings.concat(identity_verification_attributes)
+        settings.concat(enable_promotion_management_attributes)
       end
     end
 
@@ -314,5 +315,11 @@ def identity_verification_attributes
         telesign_customer_xid
       ]
     end
+
+    def enable_promotion_management_attributes
+      return [] if ::Gitlab::Saas.feature_available?(:gitlab_com_subscriptions)
+
+      %i[enable_member_promotion_management]
+    end
   end
 end
diff --git a/ee/app/services/ee/application_settings/update_service.rb b/ee/app/services/ee/application_settings/update_service.rb
index 810fccb79185265c94379104a30c995dfbc789a1..8fd53b2d3316fc303d19e4c71f8544a5b1140bbb 100644
--- a/ee/app/services/ee/application_settings/update_service.rb
+++ b/ee/app/services/ee/application_settings/update_service.rb
@@ -5,6 +5,7 @@ module ApplicationSettings
     module UpdateService
       extend ::Gitlab::Utils::Override
       extend ActiveSupport::Concern
+      include ::GitlabSubscriptions::MemberManagement::PromotionManagementUtils
 
       override :execute
       def execute
@@ -22,6 +23,8 @@ def execute
         elasticsearch_namespace_ids = params.delete(:elasticsearch_namespace_ids)
         elasticsearch_project_ids = params.delete(:elasticsearch_project_ids)
 
+        params[:enable_member_promotion_management] = get_enable_member_promotion_management
+
         if result = super
           find_or_create_elasticsearch_index if params.keys.any? { |key| key.to_s.start_with?('elasticsearch') }
           update_elasticsearch_containers(ElasticsearchIndexedNamespace, elasticsearch_namespace_ids)
@@ -120,6 +123,21 @@ def elasticsearch_helper
       def elasticsearch_client
         ::Gitlab::Elastic::Client.build(application_setting.elasticsearch_config)
       end
+
+      def get_enable_member_promotion_management
+        param_value = ActiveRecord::Type::Boolean.new.cast(params.delete(:enable_member_promotion_management))
+
+        return application_setting.enable_member_promotion_management if param_value.nil?
+        return false unless promotion_management_available?
+        return true if param_value == false && pending_member_approvals?
+
+        param_value
+      end
+
+      def pending_member_approvals?
+        ::GitlabSubscriptions::MemberManagement::SelfManaged::MaxAccessLevelMemberApprovalsFinder
+          .new(current_user).execute.any?
+      end
     end
   end
 end
diff --git a/ee/spec/controllers/admin/application_settings_controller_spec.rb b/ee/spec/controllers/admin/application_settings_controller_spec.rb
index 0b29342e8530dfb2b14a54929bc41a7b4c39e669..da955c62e56fd50b9dd6af621a6271fef0c51deb 100644
--- a/ee/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/ee/spec/controllers/admin/application_settings_controller_spec.rb
@@ -157,7 +157,9 @@
           let(:promotion_management_available) { true }
 
           before do
-            allow(controller).to receive(:promotion_management_available?).and_return(promotion_management_available)
+            allow_next_instance_of(::ApplicationSettings::UpdateService) do |instance|
+              allow(instance).to receive(:promotion_management_available?).and_return(promotion_management_available)
+            end
           end
 
           context 'with promotion management available' do
diff --git a/ee/spec/helpers/ee/application_settings_helper_spec.rb b/ee/spec/helpers/ee/application_settings_helper_spec.rb
index 5888c11261978a7b4f72d7eb7f60a67d42baf0ba..e10b5b0fd09b7e65a2258187e9453c284fde5e86 100644
--- a/ee/spec/helpers/ee/application_settings_helper_spec.rb
+++ b/ee/spec/helpers/ee/application_settings_helper_spec.rb
@@ -21,6 +21,10 @@
       expect(visible_attributes).to include(*expected_fields)
     end
 
+    it 'contains member_promotion_management parameters' do
+      expect(visible_attributes).to include(*%i[enable_member_promotion_management])
+    end
+
     context 'when identity verification is enabled' do
       before do
         stub_saas_features(identity_verification: true)
diff --git a/ee/spec/requests/api/settings_spec.rb b/ee/spec/requests/api/settings_spec.rb
index 5041b7effbf7958539e3c617e68848402f01df8d..e8cc57090773c2c0a41d16b7658604c998342713 100644
--- a/ee/spec/requests/api/settings_spec.rb
+++ b/ee/spec/requests/api/settings_spec.rb
@@ -3,6 +3,7 @@
 require 'spec_helper'
 
 RSpec.describe API::Settings, 'EE Settings', :aggregate_failures, feature_category: :shared do
+  using RSpec::Parameterized::TableSyntax
   include StubENV
 
   let(:user) { create(:user) }
@@ -238,6 +239,57 @@
         end
       end
     end
+
+    context 'with billable member management' do
+      context 'when the feature is not available' do
+        it 'does not change enable_member_promotion_management to true' do
+          put api('/application/settings', admin, admin_mode: true),
+            params: { enable_member_promotion_management: true }
+
+          expect(json_response['enable_member_promotion_management']).to eq(false)
+        end
+      end
+
+      context 'when the feature is available' do
+        before do
+          allow_next_instance_of(::ApplicationSettings::UpdateService) do |instance|
+            allow(instance).to receive(:promotion_management_available?).and_return(true)
+          end
+        end
+
+        where(param_value: [true, false])
+
+        with_them do
+          it 'changes enable_member_promotion_management' do
+            ::Gitlab::CurrentSettings.update!(enable_member_promotion_management: !param_value)
+
+            put api('/application/settings', admin, admin_mode: true),
+              params: { enable_member_promotion_management: param_value }
+
+            expect(json_response['enable_member_promotion_management']).to eq(param_value)
+          end
+        end
+
+        context 'when there are pending promotions' do
+          before do
+            allow_next_instance_of(
+              ::GitlabSubscriptions::MemberManagement::SelfManaged::MaxAccessLevelMemberApprovalsFinder
+            ) do |instance|
+              allow(instance).to receive(:execute).and_return(['mock_non_empty_return'])
+            end
+          end
+
+          it 'does not change enable_member_promotion_management to false' do
+            ::Gitlab::CurrentSettings.update!(enable_member_promotion_management: true)
+
+            put api('/application/settings', admin, admin_mode: true),
+              params: { enable_member_promotion_management: false }
+
+            expect(json_response['enable_member_promotion_management']).to eq(true)
+          end
+        end
+      end
+    end
   end
 
   shared_examples 'settings for licensed features' do