diff --git a/hyrax/app/models/complex_modality.rb b/hyrax/app/models/complex_modality.rb
index 414870fe3eb8cdf96a3cfcc82a65125311f00652..43c0eaf52b301972057f21b69e073b3ed2bb73f1 100644
--- a/hyrax/app/models/complex_modality.rb
+++ b/hyrax/app/models/complex_modality.rb
@@ -15,7 +15,7 @@ class ComplexModality < ActiveRecord::Base
   validates :s3_folder_name, uniqueness: { scope: :parent_source_identifier, message: ->(object, data) { I18n.t('rdms.errors.complex_modality.title.uniqueness', value: object.s3_folder_name) } }
 
   before_validation :set_s3_folder_name
-  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change
+  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change, :handle_meta_file_on_s3
 
   delegate :crc_dataset, to: :complex_session
   delegate :complex_subject, to: :complex_session
diff --git a/hyrax/app/models/complex_session.rb b/hyrax/app/models/complex_session.rb
index 9e906a8939baf24b3a773e378f0b9384e91378be..0a917db7c71466cd6e94027fe25b535ec8247ae4 100644
--- a/hyrax/app/models/complex_session.rb
+++ b/hyrax/app/models/complex_session.rb
@@ -17,7 +17,7 @@ class ComplexSession < ActiveRecord::Base
   validates :s3_folder_name, uniqueness: { scope: :parent_source_identifier,  message: ->(object, data) { I18n.t('rdms.errors.complex_session.title.uniqueness', value: object.s3_folder_name) } }
 
   before_validation :set_s3_folder_name
-  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change
+  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change, :handle_meta_file_on_s3
 
   delegate :crc_dataset, to: :complex_subject
 
diff --git a/hyrax/app/models/complex_subject.rb b/hyrax/app/models/complex_subject.rb
index 39486440db15f41fa2655efcb669de51c93abccc..2972cdf1dc1c3e65fbbda76ca9b76d488e1ed3b9 100644
--- a/hyrax/app/models/complex_subject.rb
+++ b/hyrax/app/models/complex_subject.rb
@@ -5,6 +5,7 @@ class ComplexSubject < ActiveRecord::Base
   include S3FileHandleable
 
   has_many :complex_sessions, foreign_key: 'parent_source_identifier', primary_key: 'source_identifier', dependent: :destroy
+  has_many :complex_modalities, through: :complex_sessions
 
   attribute :source_identifier, :string, default: -> { SecureRandom.uuid }
 
@@ -15,7 +16,7 @@ class ComplexSubject < ActiveRecord::Base
   validates :s3_folder_name, uniqueness: { scope: :parent_source_identifier,  message: ->(object, data) { I18n.t('rdms.errors.complex_subject.title.uniqueness', value: object.s3_folder_name) } }
 
   before_validation :set_s3_folder_name
-  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change
+  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change, :handle_meta_file_on_s3
 
   scope :sort_by_title, ->(source_identifier) {
     where(parent_source_identifier: source_identifier)
diff --git a/hyrax/app/models/concerns/s3_file_handleable.rb b/hyrax/app/models/concerns/s3_file_handleable.rb
index 931f661c84336a6e77b9a5a280425951a9539210..a31f3b569502889a9a980786407d866b738ddb86 100644
--- a/hyrax/app/models/concerns/s3_file_handleable.rb
+++ b/hyrax/app/models/concerns/s3_file_handleable.rb
@@ -9,4 +9,117 @@ module S3FileHandleable
 
     Hyrax::HandleS3FolderNameJob.perform_later(self.class.name, self.id, name_changes)
   end
+
+  def handle_meta_file_on_s3
+    s3 = S3StorageService.new
+    s3.init_client
+
+    crc_dataset = self.class.name == "CrcDataset" ? self.class.find(self.id) : self.crc_dataset
+    bucket_name = s3.sanitise_name(crc_dataset.id)
+    complex_modalities = self.class.name == "ComplexModality" ? [self] : self.complex_modalities.to_a.flatten
+
+    complex_modalities.each do |modality|
+      subject = modality.complex_subject
+      session = modality.complex_session
+      meta_file_key = "#{subject.s3_folder_name}/#{session.s3_folder_name}/#{modality.s3_folder_name}/meta.json"
+      json_data = prepare_json(crc_dataset, subject, session, modality)
+
+      s3.add_content(bucket_name, meta_file_key, json_data)
+    end
+  end
+
+  private
+
+  def prepare_json(crc_dataset, subject, session, modality)
+    @meta = {}
+
+    data_from_crc_dataset(crc_dataset)
+    data_from_complex_subject(subject)
+    data_from_complex_session(session)
+    data_from_complex_modality(modality)
+
+    @meta.to_json
+  end
+
+  def data_from_complex_subject(subject)
+    @meta["Subject ID"] = subject.id
+    @meta["Subject Species"] = subject.subject_species
+    @meta["Subject type"] = subject.subject_type
+    @meta["Subject sex"] = subject.subject_sex
+    @meta["Subject age"] = subject.subject_age
+  end
+
+  def data_from_complex_session(session)
+    # TODO Date recorded curruntly fetch from ComplexDate we need to confirm is this correct?
+  end
+
+  def data_from_complex_modality(modality)
+    @meta["Modality"] =  modality.modality
+  end
+
+  def data_from_crc_dataset(crc_dataset)
+    @meta["DublinCore-Title"] = crc_dataset.title[0]
+    @meta["Experiment title"] = crc_dataset.title[0]
+    @meta["DataCite-Title"] = crc_dataset.title[0]
+    @meta["DublinCore-Language"] = crc_dataset.language[0]
+    @meta["DataCite-Language"] = crc_dataset.language[0]
+    @meta["Resource Type"] = crc_dataset.resource_type[0]
+    @meta["Experiment Description"] = crc_dataset.experiment_description[0]
+    @meta["Group ID"] = "" # Complex Identifier removed
+    @meta["Animal|Ethics approval No."] = crc_dataset.approval_number
+    @meta["DublinCore-Subject"] = crc_dataset.subject.join("; ")
+    @meta["DataCite-Subject"] = crc_dataset.subject.join("; ")
+    @meta["DublinCore-Publisher"] =  crc_dataset.publisher[0]
+    @meta["DataCite-Publisher"] =  crc_dataset.publisher[0]
+    @meta["DublinCore-Coverage"] = crc_dataset.coverage
+    @meta["Software version"] = "" # TODO we don't have for now
+    @meta["Extra information"] = crc_dataset.extra_information[0]
+
+    data_from_complex_person(crc_dataset.complex_person)
+    data_from_complex_date(crc_dataset.complex_date)
+    data_from_complex_funding_reference(crc_dataset.complex_funding_reference)
+  end
+
+  def data_from_complex_person(complex_person)
+    return unless complex_person.any?
+
+    complex_person = complex_person.group_by{ |p| p.role[0] }
+
+    unless complex_person["creator"].nil?
+      @meta["Creator"] = complex_person["creator"].map{ |creator| "#{creator.first_name[0]}, #{creator.last_name[0]}" }.compact.join("; ")
+      @meta["DataCite-creatorName"] = @meta["Creator"]
+      @meta["DublinCore-Creator"] = @meta["Creator"]
+      @meta["DataCite-creatorFamilyName"] = complex_person["creator"].map{ |creator| creator.first_name[0] }.compact.join("; ")
+      @meta["DataCite-creatorGivenName"] = complex_person["creator"].map{ |creator| creator.last_name[0] }.compact.join("; ")
+      @meta["DataCite-creatorAffiliation"] = complex_person["creator"].map{ |creator| creator.affiliation[0] }.compact.join("; ")
+      @meta["DataCite-creatorNameIdentifier"] = complex_person["creator"].map{ |creator| creator.orcid[0] }.compact.join("; ")
+    end
+
+    unless complex_person["contributor"].nil?
+      @meta["contributor"] = complex_person["contributor"].map{ |contributor| "#{contributor.first_name[0]}, #{contributor.last_name[0]}" }.compact.join("; ")
+      @meta["DataCite-contributorName"] = @meta["contributor"]
+      @meta["DublinCore-Contributor"] = @meta["contributor"]
+      @meta["DataCite-contributorFamilyName"] = complex_person["contributor"].map{ |contributor| contributor.first_name[0] }.compact.join("; ")
+      @meta["DataCite-contributorGivenName"] = complex_person["contributor"].map{ |contributor| contributor.last_name[0] }.compact.join("; ")
+      @meta["DataCite-contirbutorAffiliation"] = complex_person["contributor"].map{ |contributor| contributor.affiliation[0] }.compact.join("; ")
+      @meta["DataCite-contributorNameIdentifier"] = complex_person["contributor"].map{ |contributor| contributor.orcid[0] }.compact.join("; ")
+    end
+  end
+
+  def data_from_complex_funding_reference(complex_funding_reference)
+    return unless complex_funding_reference.any?
+
+    @meta["DataCite-FundingReference"] = complex_funding_reference.map{ |funding| funding.funder_name[0] }.compact.join("; ")
+    @meta["DataCite-funderIdentifier"] = complex_funding_reference.map{ |funding| funding.funder_identifier[0] }.compact.join("; ")
+  end
+
+  def data_from_complex_date(complex_dates)
+    return unless complex_dates.any?
+
+    @meta["Record date"] = complex_dates.map{ |complex_date| complex_date.date[0] if complex_date.description[0] == "Recorded" }.compact.join("; ")
+    @meta["DataCite-dateType"] = complex_dates.map{ |complex_date| complex_date.description[0] if complex_date.description[0] != "Recorded" }.compact.join("; ")
+    @meta["DataCite-Date"] = complex_dates.map{ |complex_date| complex_date.date[0] if complex_date.description[0] != "Recorded" }.compact.join("; ")
+    @meta["DublinCore-Date"] = @meta["DataCite-Date"]
+  end
+
 end
diff --git a/hyrax/app/models/crc_dataset.rb b/hyrax/app/models/crc_dataset.rb
index 2296d31927fcf8936f9e6023403e22b3f78f03a2..053d47f0a603f6f78632fc873b2fcdbe6c28812c 100755
--- a/hyrax/app/models/crc_dataset.rb
+++ b/hyrax/app/models/crc_dataset.rb
@@ -6,12 +6,13 @@ class CrcDataset < ActiveFedora::Base
   include ::Hyrax::WorkBehavior
   include ::Hyrax::TombstoneBehavior
   include ExternalServices
+  include S3FileHandleable
   self.indexer = CrcDatasetIndexer
   # Change this to restrict which works can be added as a child.
   # self.valid_child_concerns = []
   validates :title, presence: { message: 'Your CRC dataset must have a title.' }
   validate :validate_parent_collection
-  after_save :save_work_meta_json_file_to_s3
+  after_save :save_work_meta_json_file_to_s3, :handle_meta_file_on_s3
   after_create :set_default_source_and_tombstone_status
   after_create :register_ark
 
@@ -144,6 +145,10 @@ class CrcDataset < ActiveFedora::Base
     ComplexSubject.where(parent_source_identifier: source.first)
   end
 
+  def complex_modalities
+    complex_subjects.map(&:complex_modalities)
+  end
+
   def file_sets_fast_load_metadata
     FileSetFastLoadMetadata.sort_and_filter_by_title_and_source(source.first)
   end