diff --git a/DataTree.cc b/DataTree.cc
index e748e7598b94e3fd66483e7d4568e5e154cda5a9..dac7c157b17b198532d93c7e623e72a1a79ea5aa 100644
--- a/DataTree.cc
+++ b/DataTree.cc
@@ -507,6 +507,7 @@ DataTree::AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableExcept
     throw LocalVariableException(symbol_table.getName(symb_id));
 
   local_variables_table[symb_id] = value;
+  local_variables_vector.push_back(symb_id);
 }
 
 expr_t
diff --git a/DataTree.hh b/DataTree.hh
index 5efb57bdbf4353d830cd692128006db97e07aee7..26a43860489fc76c4e79a4bea32cf6dce563467c 100644
--- a/DataTree.hh
+++ b/DataTree.hh
@@ -84,6 +84,8 @@ protected:
 
   //! Stores local variables value (maps symbol ID to corresponding node)
   map<int, expr_t> local_variables_table;
+  //! Stores the order of appearance of local variables in the model block. Needed following change in #563
+  vector<int> local_variables_vector;
 
   //! Internal implementation of AddVariable(), without the check on the lag
   VariableNode *AddVariableInternal(int symb_id, int lag);
diff --git a/DynamicModel.cc b/DynamicModel.cc
index 207066ebb168869c223387ba442307d5934c09b1..18024f2cfadae1181a97f5b33fabf13089a83212 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -3728,9 +3728,9 @@ DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const
   assert(&symbol_table == &dynamic_model.symbol_table);
 
   // Convert model local variables (need to be done first)
-  for (map<int, expr_t>::const_iterator it = local_variables_table.begin();
-       it != local_variables_table.end(); it++)
-    dynamic_model.AddLocalVariable(it->first, it->second->cloneDynamic(dynamic_model));
+  for (vector<int>::const_iterator it = local_variables_vector.begin();
+       it != local_variables_vector.end(); it++)
+    dynamic_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->cloneDynamic(dynamic_model));
 
   // Convert equations
   for (size_t i = 0; i < equations.size(); i++)
@@ -3853,9 +3853,9 @@ DynamicModel::toStatic(StaticModel &static_model) const
   assert(&symbol_table == &static_model.symbol_table);
 
   // Convert model local variables (need to be done first)
-  for (map<int, expr_t>::const_iterator it = local_variables_table.begin();
-       it != local_variables_table.end(); it++)
-    static_model.AddLocalVariable(it->first, it->second->toStatic(static_model));
+  for (vector<int>::const_iterator it = local_variables_vector.begin();
+       it != local_variables_vector.end(); it++)
+    static_model.AddLocalVariable(*it, local_variables_table.find(*it)->second->toStatic(static_model));
 
   // Convert equations
   int static_only_index = 0;
diff --git a/DynareBison.yy b/DynareBison.yy
index b8a6107c3b9f3770c55a07de22995c3e89105769..52931d891d629c100f8fb7fbc67e4b4a013a2334 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -129,7 +129,7 @@ class ParsingDriver;
 %token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL
 %token <string_val> TEX_NAME
 %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED
-%token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES PLOT_SHOCK_DECOMPOSITION
+%token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE
 %token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL
 %token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP QOQ YOY AOA
 %left COMMA
@@ -203,6 +203,7 @@ statement : parameters
           | varexo
           | varexo_det
           | predetermined_variables
+          | model_local_variable
           | change_type
           | periods
           | model
@@ -381,6 +382,8 @@ predetermined_variables : PREDETERMINED_VARIABLES predetermined_variables_list '
 
 parameters : PARAMETERS parameter_list ';';
 
+model_local_variable : MODEL_LOCAL_VARIABLE model_local_variable_list ';';
+
 named_var_elem : symbol EQUAL QUOTED_STRING
                {
                   pair<string *, string *> *pr = new pair<string *, string *>($1, $3);
@@ -525,6 +528,20 @@ predetermined_variables_list : predetermined_variables_list symbol
                                { driver.add_predetermined_variable($1); }
                              ;
 
+model_local_variable_list : model_local_variable_list symbol
+                            { driver.declare_model_local_variable($2); }
+                          | model_local_variable_list COMMA symbol
+                            { driver.declare_model_local_variable($3); }
+                          | symbol
+                            { driver.declare_model_local_variable($1); }
+                          | model_local_variable_list symbol TEX_NAME
+                            { driver.declare_model_local_variable($2, $3); }
+                          | model_local_variable_list COMMA symbol TEX_NAME
+                            { driver.declare_model_local_variable($3, $4); }
+                          | symbol TEX_NAME
+                            { driver.declare_model_local_variable($1, $2); }
+                          ;
+
 change_type : CHANGE_TYPE '(' change_type_arg ')' change_type_var_list ';'
               { driver.change_type($3, $5); }
             ;
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 9553fab4519afeb0d9a7731ab8ff21ae9210344e..092d39d9b1ca14eeca26b814975875f61b3f9cbc 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -111,6 +111,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
 <INITIAL>log_trend_var {BEGIN DYNARE_STATEMENT; return token::LOG_TREND_VAR;}
 <INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;}
 <INITIAL>parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;}
+<INITIAL>model_local_variable {BEGIN DYNARE_STATEMENT; return token::MODEL_LOCAL_VARIABLE;}
 <INITIAL>periods 	{BEGIN DYNARE_STATEMENT; return token::PERIODS;}
 <INITIAL>model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;}
 <INITIAL>estimation {BEGIN DYNARE_STATEMENT; return token::ESTIMATION;}
diff --git a/ModelTree.cc b/ModelTree.cc
index 61be06e4f5773f01b303a2c1ed821ad64fae42f4..cb3523a627c1c7070b6cccced67a765aa47d1108 100644
--- a/ModelTree.cc
+++ b/ModelTree.cc
@@ -1418,24 +1418,25 @@ ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_t
   for (size_t i = 0; i < equations.size(); i++)
     equations[i]->collectVariables(eModelLocalVariable, used_local_vars);
 
-  for (set<int>::const_iterator it = used_local_vars.begin();
-       it != used_local_vars.end(); ++it)
-    {
-      int id = *it;
-      expr_t value = local_variables_table.find(id)->second;
-      value->writeExternalFunctionOutput(output, output_type, tt, tef_terms);
-
-      if (IS_C(output_type))
-        output << "double ";
-      else if (IS_JULIA(output_type))
-        output << "  @inbounds ";
-
-      /* We append underscores to avoid name clashes with "g1" or "oo_" (see
-         also VariableNode::writeOutput) */
-      output << symbol_table.getName(id) << "__ = ";
-      value->writeOutput(output, output_type, tt, tef_terms);
-      output << ";" << endl;
-    }
+  for (vector<int>::const_iterator it = local_variables_vector.begin();
+       it != local_variables_vector.end(); it++)
+    if (used_local_vars.find(*it) != used_local_vars.end())
+      {
+        int id = *it;
+        expr_t value = local_variables_table.find(id)->second;
+        value->writeExternalFunctionOutput(output, output_type, tt, tef_terms);
+
+        if (IS_C(output_type))
+          output << "double ";
+        else if (IS_JULIA(output_type))
+          output << "  @inbounds ";
+
+        /* We append underscores to avoid name clashes with "g1" or "oo_" (see
+           also VariableNode::writeOutput) */
+        output << symbol_table.getName(id) << "__ = ";
+        value->writeOutput(output, output_type, tt, tef_terms);
+        output << ";" << endl;
+      }
 }
 
 void
@@ -1468,21 +1469,26 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t
     }
   output << "]"
          << ", \"model_local_variables\": [";
-  for (set<int>::const_iterator it = used_local_vars.begin();
-       it != used_local_vars.end(); ++it)
-    {
-      if (it != used_local_vars.begin())
-        output << ", ";
-      int id = *it;
-      expr_t value = local_variables_table.find(id)->second;
+  bool printed = false;
+  for (vector<int>::const_iterator it = local_variables_vector.begin();
+       it != local_variables_vector.end(); it++)
+    if (used_local_vars.find(*it) != used_local_vars.end())
+      {
+        int id = *it;
+        expr_t value = local_variables_table.find(id)->second;
 
-      /* We append underscores to avoid name clashes with "g1" or "oo_" (see
-         also VariableNode::writeOutput) */
-      output << "{\"variable\": \"" << symbol_table.getName(id) << "__\""
-             << ", \"value\": \"";
-      value->writeJsonOutput(output, tt, tef_terms);
-      output << "\"}" << endl;
-    }
+        if (printed)
+          output << ", ";
+        else
+          printed = true;
+
+        /* We append underscores to avoid name clashes with "g1" or "oo_" (see
+           also VariableNode::writeOutput) */
+        output << "{\"variable\": \"" << symbol_table.getName(id) << "__\""
+               << ", \"value\": \"";
+        value->writeJsonOutput(output, tt, tef_terms);
+        output << "\"}" << endl;
+      }
   output << "]";
 }
 
@@ -1660,11 +1666,11 @@ ModelTree::writeLatexModelFile(const string &basename, ExprNodeOutputType output
          << "\\footnotesize" << endl;
 
   // Write model local variables
-  for (map<int, expr_t>::const_iterator it = local_variables_table.begin();
-       it != local_variables_table.end(); it++)
+  for (vector<int>::const_iterator it = local_variables_vector.begin();
+       it != local_variables_vector.end(); it++)
     {
-      int id = it->first;
-      expr_t value = it->second;
+      int id = *it;
+      expr_t value = local_variables_table.find(id)->second;
 
       content_output << "\\begin{dmath*}" << endl
                      << symbol_table.getTeXName(id) << " = ";
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index b606365dc5778ab9fd95053f2a10af47f97d7cdf..f2615caee6e053cb19626210bb484e19816d05a9 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -2226,6 +2226,15 @@ ParsingDriver::add_model_equal_with_zero_rhs(expr_t arg)
   return add_model_equal(arg, model_tree->Zero);
 }
 
+void
+ParsingDriver::declare_model_local_variable(string *name, string *tex_name)
+{
+  declare_symbol(name, eModelLocalVariable, tex_name, NULL);
+  delete name;
+  if (tex_name != NULL)
+    delete tex_name;
+}
+
 void
 ParsingDriver::declare_and_init_model_local_variable(string *name, expr_t rhs)
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index f7bb115b366232dd3cbba59059efa519f9b1fda8..74ee8ff66a20468793d6b6f316a178a86294f9e2 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -303,6 +303,8 @@ public:
   void declare_exogenous_det(string *name, string *tex_name = NULL, vector<pair<string *, string *> *> *partition_value = NULL);
   //! Declares a parameter
   void declare_parameter(string *name, string *tex_name = NULL, vector<pair<string *, string *> *> *partition_value = NULL);
+  //! Declares a model local variable
+  void declare_model_local_variable(string *name, string *tex_name = NULL);
   //! Declares a statement local variable
   void declare_statement_local_variable(string *name);
   //! Completes a subsample statement