diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst
index 83f3b7c44c7173817442861881566a6ed0b786ed..dbe649b3284490a4e7775881496b2904a75f7259 100644
--- a/modules/io/doc/mmcif.rst
+++ b/modules/io/doc/mmcif.rst
@@ -31,6 +31,8 @@ The following categories of a mmCIF file are considered by the reader:
 * ``exptl``: Goes into :class:`MMCifInfo` as :attr:`~MMCifInfo.method`.
 * ``refine``: Goes into :class:`MMCifInfo` as :attr:`~MMCifInfo.resolution`,
   :attr:`~MMCifInfo.r_free` and :attr:`~MMCifInfo.r_work`.
+* ``em_3d_reconstruction``: Goes into :class:`MMCifInfo` as
+  :attr:`~MMCifInfo.em_resolution`.
 * ``pdbx_struct_assembly``: Used for :class:`MMCifInfoBioUnit`.
 * ``pdbx_struct_assembly_gen``: Used for :class:`MMCifInfoBioUnit`.
 * ``pdbx_struct_oper_list``: Used for :class:`MMCifInfoBioUnit`.
@@ -140,12 +142,22 @@ of the annotation available.
 
   .. attribute:: resolution
 
-    Stores the resolution of the crystal structure. Set to 0 if no value in
+    Stores the resolution of the crystal structure, obtained from the
+    ``refine.ls_d_res_high`` data item. Set to 0 if no value in
     loaded mmCIF file.
 
     Also available as :meth:`GetResolution`. May also be modified by
     :meth:`SetResolution`.
 
+  .. attribute:: em_resolution
+
+    Stores the resolution of the EM reconstruction, obtained from the
+    ``em_3d_reconstruction.resolution`` data item. Set to 0 if no value
+    in loaded mmCIF file.
+
+    Also available as :meth:`GetEMResolution`. May also be modified by
+    :meth:`SetEMResolution`.
+
   .. attribute:: r_free
 
     Stores the R-free value of the crystal structure. Set to 0 if no value in
diff --git a/modules/io/pymod/export_mmcif_io.cc b/modules/io/pymod/export_mmcif_io.cc
index f08315a4978499bfef95d2fe014a2c9e4fe74b49..bd892405f7bddb281a16cef43f68d6a981efa66c 100644
--- a/modules/io/pymod/export_mmcif_io.cc
+++ b/modules/io/pymod/export_mmcif_io.cc
@@ -507,6 +507,8 @@ void export_mmcif_io()
     .def("GetMethod", &MMCifInfo::GetMethod)
     .def("SetResolution", &MMCifInfo::SetResolution)
     .def("GetResolution", &MMCifInfo::GetResolution)
+    .def("SetEMResolution", &MMCifInfo::SetEMResolution)
+    .def("GetEMResolution", &MMCifInfo::GetEMResolution)
     .def("SetRFree", &MMCifInfo::SetRFree)
     .def("GetRFree", &MMCifInfo::GetRFree)
     .def("SetRWork", &MMCifInfo::SetRWork)
@@ -545,6 +547,8 @@ void export_mmcif_io()
     .add_property("method", &MMCifInfo::GetMethod, &MMCifInfo::SetMethod)
     .add_property("resolution", &MMCifInfo::GetResolution,
                   &MMCifInfo::SetResolution)
+    .add_property("em_resolution", &MMCifInfo::GetEMResolution,
+                  &MMCifInfo::SetEMResolution)
     .add_property("r_free", &MMCifInfo::GetRFree, &MMCifInfo::SetRFree)
     .add_property("r_work", &MMCifInfo::GetRWork, &MMCifInfo::SetRWork)
     .add_property("operations", make_function(&MMCifInfo::GetOperations,
diff --git a/modules/io/src/mol/mmcif_info.hh b/modules/io/src/mol/mmcif_info.hh
index 5114b4d9e1526d382e765d39b05d69171c7d64cc..054ecb3a626b57910ac710359434a1aeef8be04b 100644
--- a/modules/io/src/mol/mmcif_info.hh
+++ b/modules/io/src/mol/mmcif_info.hh
@@ -989,7 +989,8 @@ typedef std::map<String, MMCifEntityDesc> MMCifEntityDescMap;
 class DLLEXPORT_OST_IO MMCifInfo {
 public:
   /// \brief Create an info object.
-  MMCifInfo(): exptl_method_(""), resolution_(0), r_free_(0), r_work_(0) { }
+  MMCifInfo(): exptl_method_(""), resolution_(0), em_resolution_(0), r_free_(0),
+    r_work_(0) { }
 
   /// \brief Add an item to the list of citations
   ///
@@ -1037,6 +1038,16 @@ public:
   /// \return experiment resolution
   Real GetResolution() const { return resolution_; }
 
+  /// \brief Set EM resolution.
+  ///
+  /// \param res EM experiment resolution
+  void SetEMResolution(Real res) { em_resolution_ = res; }
+
+  /// \brief Get EM resolution.
+  ///
+  /// \return EM experiment resolution
+  Real GetEMResolution() const { return em_resolution_; }
+
   /// \brief Set R-free value.
   ///
   /// \param res experiment R-free value
@@ -1226,6 +1237,7 @@ private:
   // members
   String exptl_method_;
   Real resolution_;
+  Real em_resolution_;
   Real r_free_;
   Real r_work_;
   MMCifInfoStructDetails struct_details_;     ///< mmCIF struct category
diff --git a/modules/io/src/mol/mmcif_reader.cc b/modules/io/src/mol/mmcif_reader.cc
index 9ad17290f263753625b45c7f26e485a03fe05b0d..90970daa3c8cd963fb99deaddf8dcb0907e64550 100644
--- a/modules/io/src/mol/mmcif_reader.cc
+++ b/modules/io/src/mol/mmcif_reader.cc
@@ -397,7 +397,12 @@ bool MMCifReader::OnBeginLoop(const StarLoopDesc& header)
   this->TryStoreIdx(EPS_MON_ID, "mon_id", header);
   this->TryStoreIdx(EPS_NUM, "num", header);
   cat_available = true;
- }
+ } else if (header.GetCategory() == "em_3d_reconstruction") {
+    category_ = EM_3D_RECONSTRUCTION;
+    // optional items
+    indices_[EM_RESOLUTION] = header.GetIndex("resolution");
+    cat_available = true;
+  }
   category_counts_[category_]++;
   return cat_available;
 }
@@ -1025,6 +1030,14 @@ void MMCifReader::ParseRefine(const std::vector<StringRef>& columns)
   }
 }
 
+void MMCifReader::ParseEm3DReconstruction(const std::vector<StringRef>& columns)
+{
+  StringRef col = columns[indices_[EM_RESOLUTION]];
+  if (col.size()!=1 || (col[0]!='?' && col[0]!='.')) {
+    info_.SetEMResolution(this->TryGetReal(col, "em_3d_reconstruction.resolution"));
+  }
+}
+
 void MMCifReader::ParsePdbxStructAssembly(const std::vector<StringRef>& columns)
 {
   MMCifPSAEntry psa;
@@ -1652,6 +1665,10 @@ void MMCifReader::OnDataRow(const StarLoopDesc& header,
     LOG_TRACE("processing entity_poly_seq entry");
     this->ParseEntityPolySeq(columns);
     break;
+  case EM_3D_RECONSTRUCTION:
+    LOG_TRACE("processing em_3d_reconstruction entry");
+    this->ParseEm3DReconstruction(columns);
+    break;
   default:
     throw IOException(this->FormatDiagnostic(STAR_DIAG_ERROR,
                        "Uncatched category '"+ header.GetCategory() +"' found.",
diff --git a/modules/io/src/mol/mmcif_reader.hh b/modules/io/src/mol/mmcif_reader.hh
index 43f6cc220a8db607af23f8884edf20a35e407b71..e0b4c4c0b664e66dce8fd67ce6ea176d8bbd3064 100644
--- a/modules/io/src/mol/mmcif_reader.hh
+++ b/modules/io/src/mol/mmcif_reader.hh
@@ -343,6 +343,11 @@ protected:
   /// \param columns data row
   void ParseEntityPolySeq(const std::vector<StringRef>& columns);
 
+  /// \brief Fetch mmCIF entity_poly_seq information
+  ///
+  /// \param columns data row
+  void ParseEm3DReconstruction(const std::vector<StringRef>& columns);
+
   /// \struct types of secondary structure
   typedef enum {
     MMCIF_HELIX,
@@ -607,6 +612,11 @@ private:
     EPS_NUM
   } EntityPolySeqItems;
 
+  /// \enum items of the entity_poly_seq category
+  typedef enum {
+    EM_RESOLUTION
+  } Em3DReconstructionItems;
+
   /// \enum categories of the mmcif format
   typedef enum {
     ATOM_SITE,
@@ -633,6 +643,7 @@ private:
     PDBX_ENTITY_BRANCH,
     PDBX_ENTITY_BRANCH_LINK,
     ENTITY_POLY_SEQ,
+    EM_3D_RECONSTRUCTION,
     DONT_KNOW
   } MMCifCategory;
 
diff --git a/modules/io/tests/test_io_mmcif.py b/modules/io/tests/test_io_mmcif.py
index a1b21770993e27e37adbd15d258f99e9ce831316..37e9ac6b03cd7bf034f947504473fca74fbbe66f 100644
--- a/modules/io/tests/test_io_mmcif.py
+++ b/modules/io/tests/test_io_mmcif.py
@@ -61,6 +61,7 @@ class TestMMCifInfo(unittest.TestCase):
     i = io.MMCifInfo()
     i.SetMethod('Deep-Fry')
     i.SetResolution(2.0)
+    i.SetEMResolution(3.0)
     i.AddCitation(c)
     s.append('Bar')
     i.AddAuthorsToCitation('ID', s)
@@ -74,6 +75,7 @@ class TestMMCifInfo(unittest.TestCase):
 
     self.assertEqual(i.GetMethod(), 'Deep-Fry')
     self.assertEqual(i.GetResolution(), 2.0)
+    self.assertEqual(i.GetEMResolution(), 3.0)
 
 
   def test_mmcifinfo_biounit(self):