diff --git a/DynareBison.yy b/DynareBison.yy
index 5a54e1c094a9fa726bfe4c52a135c3dea057bac1..8a3b3a18890b938fdece481dbb31b35185926c9b 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -119,7 +119,7 @@ class ParsingDriver;
 %token <string_val> QUOTED_STRING
 %token QZ_CRITERIUM FULL
 %token RELATIVE_IRF REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE
-%token SHOCKS SHOCK_DECOMPOSITION SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED SMOOTHER STACK_SOLVE_ALGO SOLVE_ALGO
+%token SHOCKS SHOCK_DECOMPOSITION SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED SMOOTHER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO
 %token STDERR STEADY STOCH_SIMUL
 %token TEX RAMSEY_POLICY PLANNER_DISCOUNT
 %token <string_val> TEX_NAME
@@ -240,6 +240,7 @@ statement : parameters
           | markov_switching
           | svar
           | external_function
+          | steady_state_model
           ;
 
 dsample : DSAMPLE INT_NUMBER ';'
@@ -1649,6 +1650,18 @@ conditional_forecast_paths_shock_elem : VAR symbol ';' PERIODS period_list ';' V
                                         { driver.add_det_shock($2, true); }
                                       ;
 
+steady_state_model : STEADY_STATE_MODEL ';' { driver.begin_steady_state_model(); }
+                     steady_state_equation_list END { driver.reset_data_tree(); }
+                   ;
+
+steady_state_equation_list : steady_state_equation_list steady_state_equation
+                           | steady_state_equation
+                           ;
+
+steady_state_equation : symbol EQUAL expression ';'
+                        { driver.add_steady_state_model_equal($1, $3); }
+                      ;
+
 o_dr_algo : DR_ALGO EQUAL INT_NUMBER {
                                        if (*$3 == string("0"))
                                          driver.warning("dr_algo option is now deprecated, and may be removed in a future version of Dynare");
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 1dec133cd6324a412dd11993509e0286c8b8682c..5fd8c51813d011cb6b3115435e059b511d8637d0 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -154,6 +154,7 @@ int sigma_e = 0;
 
  /* Begin of a Dynare block */
 <INITIAL>model {BEGIN DYNARE_BLOCK; return token::MODEL;}
+<INITIAL>steady_state_model {BEGIN DYNARE_BLOCK; return token::STEADY_STATE_MODEL;}
 <INITIAL>initval {BEGIN DYNARE_BLOCK; return token::INITVAL;}
 <INITIAL>endval {BEGIN DYNARE_BLOCK; return token::ENDVAL;}
 <INITIAL>histval {BEGIN DYNARE_BLOCK; return token::HISTVAL;}
diff --git a/ExprNode.cc b/ExprNode.cc
index 0d381ac5d2b1ff6fcd73c731dc4a4d0915fb531d..6588557a77da04d447b846c9eb185a584d3f0617 100644
--- a/ExprNode.cc
+++ b/ExprNode.cc
@@ -523,14 +523,13 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
   switch (type)
     {
     case eParameter:
-      if (output_type == oMatlabOutsideModel)
+      if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile)
         output << "M_.params" << "(" << tsid + 1 << ")";
       else
         output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type);
       break;
 
     case eModelLocalVariable:
-    case eModFileLocalVariable:
       if (output_type == oMatlabDynamicModelSparse || output_type == oMatlabStaticModelSparse || output_type == oMatlabDynamicModelSparseLocalTemporaryTerms)
         {
           output << "(";
@@ -541,6 +540,10 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
         output << datatree.symbol_table.getName(symb_id);
       break;
 
+    case eModFileLocalVariable:
+      output << datatree.symbol_table.getName(symb_id);
+      break;
+
     case eEndogenous:
       switch (output_type)
         {
@@ -570,6 +573,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
         case oMatlabDynamicSteadyStateOperator:
           output << "oo_.steady_state(" << tsid + 1 << ")";
           break;
+        case oSteadyStateFile:
+          output << "ys_(" << tsid + 1 << ")";
+          break;
         default:
           assert(false);
         }
@@ -608,6 +614,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
         case oMatlabDynamicSteadyStateOperator:
           output <<  "oo_.exo_steady_state(" << i << ")";
           break;
+        case oSteadyStateFile:
+          output << "exo_(" << i << ")";
+          break;
         default:
           assert(false);
         }
@@ -646,6 +655,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
         case oMatlabDynamicSteadyStateOperator:
           output <<  "oo_.exo_det_steady_state(" << tsid + 1 << ")";
           break;
+        case oSteadyStateFile:
+          output << "exo_(" << i << ")";
+          break;
         default:
           assert(false);
         }
diff --git a/ExprNode.hh b/ExprNode.hh
index 52a6b04bc5ad9c4063488c0143c33c13489c40c8..ecc4cbf9c64e6f8168859d0abf5900ee407e0317 100644
--- a/ExprNode.hh
+++ b/ExprNode.hh
@@ -71,7 +71,8 @@ enum ExprNodeOutputType
     oLatexDynamicSteadyStateOperator,             //!< LaTeX code, dynamic model steady state declarations
     oMatlabDynamicSteadyStateOperator,            //!< Matlab code, dynamic model steady state declarations
     oMatlabDynamicModelSparseSteadyStateOperator, //!< Matlab code, dynamic block decomposed model steady state declarations
-    oMatlabDynamicModelSparseLocalTemporaryTerms  //!< Matlab code, dynamic block decomposed model local temporary_terms
+    oMatlabDynamicModelSparseLocalTemporaryTerms, //!< Matlab code, dynamic block decomposed model local temporary_terms
+    oSteadyStateFile                              //!< Matlab code, in the generated steady state file
   };
 
 #define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel     \
@@ -81,7 +82,8 @@ enum ExprNodeOutputType
                                 || (output_type) == oMatlabDynamicModelSparse \
                                 || (output_type) == oMatlabDynamicModelSparseLocalTemporaryTerms \
                                 || (output_type) == oMatlabDynamicSteadyStateOperator \
-                                || (output_type) == oMatlabDynamicModelSparseSteadyStateOperator)
+                                || (output_type) == oMatlabDynamicModelSparseSteadyStateOperator \
+                                || (output_type) == oSteadyStateFile)
 
 #define IS_C(output_type) ((output_type) == oCDynamicModel)
 
diff --git a/Makefile.am b/Makefile.am
index a9d6da685268612c15f5a9b4d278324503aa767d..8c80d0d806fdf5de167276819cc41f6276f49961 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,7 +47,9 @@ dynare_m_SOURCES = \
 	CodeInterpreter.hh \
 	FlexLexer.h \
 	ExternalFunctionsTable.cc \
-	ExternalFunctionsTable.hh
+	ExternalFunctionsTable.hh \
+	SteadyStateModel.hh \
+	SteadyStateModel.cc
 
 # The -I. is for <FlexLexer.h>
 dynare_m_CPPFLAGS = $(BOOST_CPPFLAGS) -I.
diff --git a/ModFile.cc b/ModFile.cc
index c664940419caf1381294b88d5198020e39572aa9..bc754f00f0c3e71379f405c3e45eabf9c5507eb3 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -24,8 +24,9 @@
 #include "ModFile.hh"
 
 ModFile::ModFile() : expressions_tree(symbol_table, num_constants, external_functions_table),
-                     static_model(symbol_table, num_constants, external_functions_table),
+                     steady_state_model(symbol_table, num_constants, external_functions_table),
                      dynamic_model(symbol_table, num_constants, external_functions_table),
+                     static_model(symbol_table, num_constants, external_functions_table),
                      linear(false), block(false), byte_code(false),
                      use_dll(false), no_static(false)
 {
@@ -439,5 +440,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all
         }
     }
 
+  // Create steady state file
+  steady_state_model.writeSteadyStateFile(basename);
+
   cout << "done" << endl;
 }
diff --git a/ModFile.hh b/ModFile.hh
index 01d3d368ce671ec43a9e3932d0c5fb5f6da3abe0..57612a3e79d537e5fee9710a282841b73a0cecc5 100644
--- a/ModFile.hh
+++ b/ModFile.hh
@@ -30,6 +30,7 @@ using namespace std;
 #include "NumericalInitialization.hh"
 #include "StaticModel.hh"
 #include "DynamicModel.hh"
+#include "SteadyStateModel.hh"
 #include "Statement.hh"
 #include "ExternalFunctionsTable.hh"
 
@@ -47,10 +48,12 @@ public:
   NumericalConstants num_constants;
   //! Expressions outside model block
   DataTree expressions_tree;
-  //! Static Dll model
-  StaticModel static_model;
-  //! Dynamic model
+  //! Static model, as declared in the "steady_state_model" block if present
+  SteadyStateModel steady_state_model;
+  //! Dynamic model, as declared in the "model" block
   DynamicModel dynamic_model;
+  //! Static model, as derived from the "model" block when leads and lags have been removed
+  StaticModel static_model;
   //! Option linear
   bool linear;
 
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 4be917cbbb90a8f13d950b16ba193333ae2c1e4e..1e6d0796dd1f28ea211af900526dfb65d9cde048 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -1391,17 +1391,27 @@ ParsingDriver::add_model_equal_with_zero_rhs(NodeID arg)
 void
 ParsingDriver::declare_and_init_model_local_variable(string *name, NodeID rhs)
 {
+  int symb_id;
   try
     {
-      mod_file->symbol_table.addSymbol(*name, eModelLocalVariable);
+      symb_id = mod_file->symbol_table.addSymbol(*name, eModelLocalVariable);
     }
   catch (SymbolTable::AlreadyDeclaredException &e)
     {
-      error("Local model variable " + *name + " declared twice.");
+      // It can have already been declared in a steady_state_model block, check that it is indeed a ModelLocalVariable
+      symb_id = mod_file->symbol_table.getID(*name);
+      if (mod_file->symbol_table.getType(symb_id) != eModelLocalVariable)
+        error(*name + " has wrong type, you cannot use it within as left-hand side of a pound ('#') expression");
     }
 
-  int symb_id = mod_file->symbol_table.getID(*name);
-  model_tree->AddLocalVariable(symb_id, rhs);
+  try
+    {
+      model_tree->AddLocalVariable(symb_id, rhs);
+    }
+  catch (DataTree::LocalVariableException &e)
+    {
+      error("Local model variable " + *name + " declared twice.");
+    }
   delete name;
 }
 
@@ -1834,3 +1844,43 @@ ParsingDriver::add_native(const char *s)
 {
   mod_file->addStatement(new NativeStatement(s));
 }
+
+void
+ParsingDriver::begin_steady_state_model()
+{
+  set_current_data_tree(&mod_file->steady_state_model);
+}
+
+void
+ParsingDriver::add_steady_state_model_equal(string *varname, NodeID expr)
+{
+  int id;
+  try
+    {
+      id = mod_file->symbol_table.getID(*varname);
+    }
+  catch (SymbolTable::UnknownSymbolNameException &e)
+    {
+      // Unknown symbol, declare it as a ModFileLocalVariable
+      id = mod_file->symbol_table.addSymbol(*varname, eModFileLocalVariable);
+    }
+
+  SymbolType type = mod_file->symbol_table.getType(id);
+  if (type != eEndogenous && type != eModFileLocalVariable)
+    error(*varname + " has incorrect type");
+
+  try
+    {
+      mod_file->steady_state_model.addDefinition(id, expr);
+    }
+  catch(SteadyStateModel::AlreadyDefinedException &e)
+    {
+      error(*varname + " has already been defined in the steady state block");
+    }
+  catch(SteadyStateModel::UndefinedVariableException &e)
+    {
+      error(e.varname + " is not yet initialized at this point");
+    }
+
+  delete varname;
+}
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index ea91235f87cce737087a1c9d627f0933a2b6e218..43cace79084241ac63bfaa53bb844ff4632a5318 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -493,6 +493,10 @@ public:
   void add_native(const char *s);
   //! Resets data_tree and model_tree pointers to default (i.e. mod_file->expressions_tree)
   void reset_data_tree();
+  //! Begin a steady_state_model block
+  void begin_steady_state_model();
+  //! Add an assignment equation in steady_state_model block
+  void add_steady_state_model_equal(string *varname, NodeID expr);
 };
 
 #endif // ! PARSING_DRIVER_HH
diff --git a/StaticModel.hh b/StaticModel.hh
index d4353b3e7fa0c6dc340cc8baf6b2820feb71e2af..b806bd76e399b1403656b9196a6bab0eecc15fef 100644
--- a/StaticModel.hh
+++ b/StaticModel.hh
@@ -26,7 +26,7 @@ using namespace std;
 
 #include "ModelTree.hh"
 
-//! Stores a static model
+//! Stores a static model, as derived from the "model" block when leads and lags have been removed
 class StaticModel : public ModelTree
 {
 private:
diff --git a/SteadyStateModel.cc b/SteadyStateModel.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b71c94e08032665866a5837ad61cea3e2a4a837c
--- /dev/null
+++ b/SteadyStateModel.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010 Dynare Team
+ *
+ * This file is part of Dynare.
+ *
+ * Dynare is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dynare is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cassert>
+#include <algorithm>
+
+#include "SteadyStateModel.hh"
+
+SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table_arg) :
+  DataTree(symbol_table_arg, num_constants, external_functions_table)
+{
+}
+
+void
+SteadyStateModel::addDefinition(int symb_id, NodeID expr) throw (UndefinedVariableException, AlreadyDefinedException)
+{
+  assert(symbol_table.getType(symb_id) == eEndogenous
+         || symbol_table.getType(symb_id) == eModFileLocalVariable);
+
+  // Check that symbol is not already defined
+  if (find(recursive_order.begin(), recursive_order.end(), symb_id)
+      != recursive_order.end())
+    throw AlreadyDefinedException(symbol_table.getName(symb_id));
+
+  // Check that expression has no undefined symbol
+  set<pair<int, int> > used_symbols;
+  expr->collectVariables(eEndogenous, used_symbols);
+  expr->collectVariables(eModFileLocalVariable, used_symbols);
+  for(set<pair<int, int> >::const_iterator it = used_symbols.begin();
+      it != used_symbols.end(); it++)
+    if (find(recursive_order.begin(), recursive_order.end(), it->first)
+        == recursive_order.end())
+      throw UndefinedVariableException(symbol_table.getName(it->first));
+
+  // Add the variable
+  recursive_order.push_back(symb_id);
+  def_table[symb_id] = AddEqual(AddVariable(symb_id), expr);
+}
+
+void
+SteadyStateModel::writeSteadyStateFile(const string &basename) const
+{
+  if (recursive_order.size() == 0)
+    return;
+
+  string filename = basename + "_steadystate.m";
+
+  ofstream output;
+  output.open(filename.c_str(), ios::out | ios::binary);
+  if (!output.is_open())
+    {
+      cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
+      exit(EXIT_FAILURE);
+    }
+
+  output << "function [ys_, check_] = " << basename << "_steadystate(ys_orig_, exo_)" << endl
+         << "% Steady state generated by Dynare preprocessor" << endl
+         << "    global M_" << endl
+         << "    ys_=zeros(" << symbol_table.orig_endo_nbr() << ",1);" << endl;
+
+  for(size_t i = 0; i < recursive_order.size(); i++)
+    {
+      output << "    ";
+      map<int, NodeID>::const_iterator it = def_table.find(recursive_order[i]);
+      it->second->writeOutput(output, oSteadyStateFile);
+      output << ";" << endl;
+    }
+  output << "    check_=0;" << endl
+         << "end" << endl;
+}
+
diff --git a/SteadyStateModel.hh b/SteadyStateModel.hh
new file mode 100644
index 0000000000000000000000000000000000000000..9c609cf51c4e8c6c54d83ceadda4b64e50d7a3af
--- /dev/null
+++ b/SteadyStateModel.hh
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Dynare Team
+ *
+ * This file is part of Dynare.
+ *
+ * Dynare is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dynare is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STEADY_STATE_MODEL_HH
+#define _STEADY_STATE_MODEL_HH
+
+#include "DataTree.hh"
+
+class SteadyStateModel : public DataTree
+{
+private:
+  //! Associates a symbol ID to an expression of the form "var = expr"
+  map<int, NodeID> def_table;
+  vector<int> recursive_order;
+
+public:
+  class AlreadyDefinedException
+  {
+  public:
+    const string &varname;
+    AlreadyDefinedException(const string &varname_arg) : varname(varname_arg) {}
+  };
+  class UndefinedVariableException
+  {
+  public:
+    const string &varname;
+    UndefinedVariableException(const string &varname_arg) : varname(varname_arg) {}
+  };
+
+  SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table_arg);
+  //! Add an expression of the form "var = expr;"
+  void addDefinition(int symb_id, NodeID expr) throw (UndefinedVariableException, AlreadyDefinedException);
+  //! Write the steady state file
+  void writeSteadyStateFile(const string &basename) const;
+};
+
+#endif