diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst
index 7b1a62eba4771cfd949b6cc4cc26a8d952f0bd36..8b001673b6c4c76c6f0902591c3a7eea85baab52 100644
--- a/doc/manual/source/the-model-file.rst
+++ b/doc/manual/source/the-model-file.rst
@@ -4668,9 +4668,9 @@ that have been left free.
 
     The ``perfect_foresight_controlled_paths`` block requires that the
     :opt:`stack_solve_algo <stack_solve_algo = INTEGER>` option be equal to
-    either ``0``, ``1``, ``2``, ``3`` or ``6``, and is incompatible with the
-    :opt:`block`, :opt:`linear` and :opt:`bytecode` options of the :bck:`model`
-    block.
+    either ``0``, ``1``, ``2``, ``3``, ``6`` or ``7``, and is incompatible with
+    the :opt:`block`, :opt:`linear` and :opt:`bytecode` options of the
+    :bck:`model` block.
 
     *Options*
 
diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver_core.m b/matlab/perfect-foresight-models/perfect_foresight_solver_core.m
index c7e376f29fdfa334efb4c6812453a09a1e60bdb8..c1977137cc03c5b745a6058cff2537351d634c9f 100644
--- a/matlab/perfect-foresight-models/perfect_foresight_solver_core.m
+++ b/matlab/perfect-foresight-models/perfect_foresight_solver_core.m
@@ -78,8 +78,11 @@ end
 
 if ~isempty(controlled_paths_by_period)
     assert(nargout >= 6); % Ensure modified exos are used
-    if ~ismember(options_.stack_solve_algo, [0 1 2 3 6])
-        error('perfect_foresight_controlled_paths is only available with stack_solve_algo option equal to 0, 1, 2, 3 or 6')
+    if ~ismember(options_.stack_solve_algo, [0 1 2 3 6 7])
+        error('perfect_foresight_controlled_paths is only available with stack_solve_algo option equal to 0, 1, 2, 3, 6 or 7')
+    end
+    if options_.stack_solve_algo == 7 && ismember(options_.solve_algo, [10, 11])
+        error('perfect_foresight_controlled_paths is not available for mixed-complementarity problems (LMMCP or PATH solvers)')
     end
     if options_.bytecode
         error('perfect_foresight_controlled_paths is not available with the bytecode option')
@@ -157,7 +160,7 @@ else
                     end
                     [y, success] = solve_stacked_linear_problem(y, exo_simul, steady_state, exo_steady_state, M_, options_);
                 else
-                    [y, success, maxerror] = solve_stacked_problem(y, exo_simul, steady_state, M_, options_);
+                    [y, success, maxerror, exo_simul] = solve_stacked_problem(y, exo_simul, steady_state, controlled_paths_by_period, M_, options_);
                 end
               otherwise
                 error('Invalid value of stack_solve_algo option!')
diff --git a/matlab/perfect-foresight-models/solve_stacked_problem.m b/matlab/perfect-foresight-models/solve_stacked_problem.m
index 61a7b3294136de34150b71205749cdee62da3974..841b7c1ef72adbe387835905e2d9f15c781556d5 100644
--- a/matlab/perfect-foresight-models/solve_stacked_problem.m
+++ b/matlab/perfect-foresight-models/solve_stacked_problem.m
@@ -1,20 +1,23 @@
-function [endogenousvariables, success, maxerror] = solve_stacked_problem(endogenousvariables, exogenousvariables, steadystate, M_, options_)
+function [endogenousvariables, success, maxerror, exogenousvariables] = solve_stacked_problem(endogenousvariables, exogenousvariables, steadystate, controlled_paths_by_period, M_, options_)
 % [endogenousvariables, success, maxerror] = solve_stacked_problem(endogenousvariables, exogenousvariables, steadystate, M_, options_)
 % Solves the perfect foresight model using dynare_solve
 %
 % INPUTS
-% - endogenousvariables [double] N*T array, paths for the endogenous variables (initial guess).
-% - exogenousvariables  [double] T*M array, paths for the exogenous variables.
+% - endogenousvariables [double] N*(T+M_.maximum_lag+M_.maximum_lead) array, paths for the endogenous variables (initial guess).
+% - exogenousvariables  [double] (T+M_.maximum_lag+M_.maximum_lead)*M array, paths for the exogenous variables.
 % - steadystate         [double] N*1 array, steady state for the endogenous variables.
+%   - controlled_paths_by_period [struct] data from perfect_foresight_controlled_paths block
 % - M_                   [struct] contains a description of the model.
 % - options_             [struct] contains various options.
 %
 % OUTPUTS
-% - endogenousvariables [double] N*T array, paths for the endogenous variables (solution of the perfect foresight model).
+% - endogenousvariables [double] N*(T+M_.maximum_lag+M_.maximum_lead) array, paths for the endogenous variables (solution of the perfect foresight model).
 % - success             [logical] Whether a solution was found
 % - maxerror            [double] 1-norm of the residual
+% - exogenousvariables  [double] (T+M_.maximum_lag+M_.maximum_lead)*M array, paths for the exogenous variables
+%                                (may be modified if perfect_foresight_controlled_paths present)
 
-% Copyright © 2015-2024 Dynare Team
+% Copyright © 2015-2025 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -46,6 +49,7 @@ end
 z = endogenousvariables(:,M_.maximum_lag+(1:periods));
 
 if (options_.solve_algo == 10 || options_.solve_algo == 11)% mixed complementarity problem
+    assert(isempty(controlled_paths_by_period))
     [lb, ub] = feval(sprintf('%s.dynamic_complementarity_conditions', M_.fname), M_.params);
     if options_.linear_approximation
         lb = lb - steadystate_y;
@@ -70,10 +74,28 @@ if (options_.solve_algo == 10 || options_.solve_algo == 11)% mixed complementari
                                                  M_.dynamic_mcp_equations_reordering);
     eq_to_ignore=find(isfinite(lb) | isfinite(ub));
 
-else
+elseif isempty(controlled_paths_by_period)
     [y, check, res, ~, errorcode] = dynare_solve(@perfect_foresight_problem, z(:), ...
                                                options_.simul.maxit, options_.dynatol.f, options_.dynatol.x, ...
                                                options_, y0, yT, exogenousvariables, M_.params, steadystate, periods, M_, options_);
+else
+    for p = 1:periods
+        if isempty(controlled_paths_by_period(p).exogenize_id)
+            continue
+        end
+        z(controlled_paths_by_period(p).exogenize_id,p) = exogenousvariables(p+M_.maximum_lag,controlled_paths_by_period(p).endogenize_id);
+    end
+
+    % call the following in a wrapper, that is then passed to dynare_solve
+    % A = controlled_paths_substitute_stacked_jacobian(A, y, y0, yT, exogenousvariables, steadystate, controlled_paths_by_period, M_);
+
+    for p = 1:periods
+        if isempty(controlled_paths_by_period(p).exogenize_id)
+            continue
+        end
+        exogenousvariables(p+M_.maximum_lag,controlled_paths_by_period(p).endogenize_id) = y(controlled_paths_by_period(p).exogenize_id+p*M_.endo_nbr);
+        y(controlled_paths_by_period(p).exogenize_id+p*M_.endo_nbr) = controlled_paths_by_period(p).values;
+    end
 end
 
 if all(imag(y)<.1*options_.dynatol.x)
diff --git a/meson.build b/meson.build
index 05a4f6b6af075b92a5a7652748d509c29d05d3ce..f52e708e87abb9d09f6ae8355d7e5c209555eb49 100644
--- a/meson.build
+++ b/meson.build
@@ -1627,6 +1627,7 @@ mod_and_m_tests = [
                'deprecated/ramst.mod' ] },
   { 'test' : [ 'deterministic_simulations/ramst_pf_controlled_paths.mod',
                'deterministic_simulations/ramst_pf_controlled_paths_lbj.mod',
+               'deterministic_simulations/ramst_pf_controlled_paths_ssa7.mod',
                'deterministic_simulations/ramst_pf_controlled_paths_check.mod' ],
     'extra' : [ 'deterministic_simulations/ramst_pf_controlled_paths_common.inc'] },
   { 'test' : [ 'deterministic_simulations/ramst_pfwee_controlled_paths.mod' ],
diff --git a/tests/deterministic_simulations/ramst_pf_controlled_paths_check.mod b/tests/deterministic_simulations/ramst_pf_controlled_paths_check.mod
index b370f6001d46f05df98ad52dc16b1320ed9e0a48..393e398c6fb2b90e794caabe351028f2a90faef4 100644
--- a/tests/deterministic_simulations/ramst_pf_controlled_paths_check.mod
+++ b/tests/deterministic_simulations/ramst_pf_controlled_paths_check.mod
@@ -1,4 +1,4 @@
-/* Checks that exogenous computed by ramst_pf_controlled_paths{,lbj}.mod actually give back the
+/* Checks that exogenous computed by ramst_pf_controlled_paths{,lbj,ssa7}.mod actually give back the
    expected endogenous variables */
 
 @#define shocks = false
@@ -33,3 +33,18 @@ perfect_foresight_solver;
 if max(max(abs(oo_.endo_simul - S1.oo_.endo_simul))) > options_.dynatol.x
     error('perfect_foresight_controlled_paths gives wrong result with stack_solve_algo=1')
 end
+
+
+// stack_solve_algo=7
+
+S7 = load('ramst_pf_controlled_paths_ssa7/Output/ramst_pf_controlled_paths_ssa7_results.mat');
+
+perfect_foresight_setup(periods=30);
+
+oo_.exo_simul = S7.oo_.exo_simul;
+
+perfect_foresight_solver;
+
+if max(max(abs(oo_.endo_simul - S7.oo_.endo_simul))) > options_.dynatol.x
+    error('perfect_foresight_controlled_paths gives wrong result with stack_solve_algo=7')
+end
diff --git a/tests/deterministic_simulations/ramst_pf_controlled_paths_ssa7.mod b/tests/deterministic_simulations/ramst_pf_controlled_paths_ssa7.mod
new file mode 100644
index 0000000000000000000000000000000000000000..2fe4958a9d97373c45cc1856b947706e19e2423e
--- /dev/null
+++ b/tests/deterministic_simulations/ramst_pf_controlled_paths_ssa7.mod
@@ -0,0 +1,17 @@
+// Performs a simulation with a perfect_foresight_controlled_paths block
+// with the stack_solve_algo=7
+
+@#define shocks = true
+@#include "ramst_pf_controlled_paths_common.inc"
+
+perfect_foresight_setup(periods=30, first_simulation_period = 2001Y);
+perfect_foresight_solver(stack_solve_algo = 7);
+
+if ~oo_.deterministic_simulation.status
+   error('Perfect foresight simulation failed')
+end
+
+if oo_.endo_simul(1, 3) ~= 1.6 || any(oo_.endo_simul(1, 5:6) ~= 1.7) || any(oo_.endo_simul(2, 8:10) ~= 13) ...
+   || any(oo_.endo_simul(3, 4:6) ~= 0.5) || oo_.exo_simul(2, 1) ~= 1.2
+   error('Perfect foresight with controlled paths failed')
+end